ส่วนหัวคำขอข้ามแหล่งกำเนิด (CORS) ด้วยส่วนหัว PHP


146

ฉันมีสคริปต์ PHP ง่าย ๆ ที่ฉันพยายามขอ CORS ข้ามโดเมน:

<?php
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: *");
...

แต่ฉันยังคงได้รับข้อผิดพลาด:

X-Requested-Withไม่อนุญาตให้ใช้ฟิลด์ส่วนหัวคำขอAccess-Control-Allow-Headers

มีอะไรฉันหายไป?

คำตอบ:


59

Access-Control-Allow-Headersไม่อนุญาตให้*เป็นค่าที่ยอมรับดูเอกสาร Mozilla ที่นี่

แทนเครื่องหมายดอกจันคุณควรส่งส่วนหัวที่ยอมรับได้ (ก่อนอื่นX-Requested-Withตามที่ระบุไว้)


289

การจัดการคำขอ CORS อย่างเหมาะสมนั้นมีส่วนเกี่ยวข้องมากกว่า นี่คือฟังก์ชั่นที่จะตอบสนองได้อย่างเต็มที่มากขึ้น (และถูกต้อง)

/**
 *  An example CORS-compliant method.  It will allow any GET, POST, or OPTIONS requests from any
 *  origin.
 *
 *  In a production environment, you probably want to be more restrictive, but this gives you
 *  the general idea of what is involved.  For the nitty-gritty low-down, read:
 *
 *  - https://developer.mozilla.org/en/HTTP_access_control
 *  - http://www.w3.org/TR/cors/
 *
 */
function cors() {

    // Allow from any origin
    if (isset($_SERVER['HTTP_ORIGIN'])) {
        // Decide if the origin in $_SERVER['HTTP_ORIGIN'] is one
        // you want to allow, and if so:
        header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
        header('Access-Control-Allow-Credentials: true');
        header('Access-Control-Max-Age: 86400');    // cache for 1 day
    }

    // Access-Control headers are received during OPTIONS requests
    if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {

        if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']))
            // may also be using PUT, PATCH, HEAD etc
            header("Access-Control-Allow-Methods: GET, POST, OPTIONS");         

        if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
            header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");

        exit(0);
    }

    echo "You have CORS!";
}

32
โปรดทราบว่าการส่งค่า HTTP Origin กลับเป็นแหล่งกำเนิดที่ได้รับอนุญาตจะอนุญาตให้ทุกคนส่งคำขอถึงคุณด้วยคุกกี้ดังนั้นจึงอาจขโมยเซสชันจากผู้ใช้ที่ลงชื่อเข้าใช้ไซต์ของคุณจากนั้นดูหน้าของผู้โจมตี คุณต้องการส่ง '*' (ซึ่งจะไม่อนุญาตให้ใช้คุกกี้เพื่อป้องกันการขโมยเซสชัน) หรือโดเมนเฉพาะที่คุณต้องการให้เว็บไซต์ทำงาน
จูลส์

1
ตกลง ในทางปฏิบัติคุณอาจไม่อนุญาตให้เพียงแค่โดเมนเก่า ๆ ที่ใช้บริการ CORS ของคุณคุณจะ จำกัด เฉพาะบางชุดที่คุณตัดสินใจเชื่อถือ
slashingweapon

FYI แก้ปัญหานี้เท่านั้นทำงานสำหรับฉันในLinux serverในIISเหตุผลบางอย่างก็ไม่ได้ทำงานผมไม่ทราบถ้าโฮสติ้งของฉันหรือเพียงแค่มันไม่เหมาะสำหรับIIS
ncubica

1
ขอบคุณ! ต้องบุ๊คมาร์คคำตอบนี้ น่าเสียดายที่เราไม่สามารถทำเครื่องหมายคำตอบนี้เป็นคำตอบใหม่ได้
Ascherer

1
สิ่งเดียวที่ใช้งานได้จริง! .. เพียงแค่เปลี่ยนการควบคุมการอนุญาตให้เข้าถึง: เพื่อการควบคุมการอนุญาตให้เข้าถึง: {$ _SERVER ['HTTP_ORIGIN']}}
Renan Franca

60

ฉันได้รับข้อผิดพลาดเดียวกันและแก้ไขด้วย PHP ต่อไปนี้ในสคริปต์ส่วนท้ายของฉัน:

header('Access-Control-Allow-Origin: *');

header('Access-Control-Allow-Methods: GET, POST');

header("Access-Control-Allow-Headers: X-Requested-With");

35

คำอธิบายมากมายทางอินเทอร์เน็ตไม่ได้กล่าวถึงว่าการระบุAccess-Control-Allow-Originไม่เพียงพอ นี่เป็นตัวอย่างที่สมบูรณ์แบบสำหรับฉัน:

<?php
    if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
        header('Access-Control-Allow-Origin: *');
        header('Access-Control-Allow-Methods: POST, GET, DELETE, PUT, PATCH, OPTIONS');
        header('Access-Control-Allow-Headers: token, Content-Type');
        header('Access-Control-Max-Age: 1728000');
        header('Content-Length: 0');
        header('Content-Type: text/plain');
        die();
    }

    header('Access-Control-Allow-Origin: *');
    header('Content-Type: application/json');

    $ret = [
        'result' => 'OK',
    ];
    print json_encode($ret);

1
โปรดอธิบายว่าทำไมมันไม่พอและตัวอย่างที่น้อยที่สุดก็พอ
halfpastfour.am

น่าเสียดายที่ฉันจำไม่ได้แน่นอนและตอนนี้ฉันไม่มีเวลาตรวจสอบอีก แต่เท่าที่ฉันจำได้มีข้อสันนิษฐานเบื้องต้นจากทางเว็บเบราว์เซอร์ / เบราว์เซอร์ซึ่งทำให้มันไม่ทำงาน นี่คือรหัสขั้นต่ำที่เหมาะกับฉัน
Csongor Halmai

24

ฉันจัดการเพื่อรับ dropzone และปลั๊กอินอื่น ๆ เพื่อทำงานกับการแก้ไขนี้ (แบ็กเอนด์ angularjs + php)

 header('Access-Control-Allow-Origin: *'); 
    header("Access-Control-Allow-Credentials: true");
    header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');
    header('Access-Control-Max-Age: 1000');
    header('Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token , Authorization');

เพิ่มสิ่งนี้ใน upload.php ของคุณหรือสถานที่ที่คุณจะส่งคำขอของคุณ (ตัวอย่างเช่นถ้าคุณมี upload.html และคุณต้องแนบไฟล์ไปที่ upload.php จากนั้นคัดลอกและวาง 4 บรรทัดเหล่านี้) นอกจากนี้หากคุณใช้ปลั๊กอิน / แอดออน CORS ใน chrome / mozilla ต้องแน่ใจว่าสลับมันมากกว่าหนึ่งครั้งเพื่อให้ CORS เปิดใช้งาน


15

หากคุณต้องการสร้างบริการ CORS จาก PHP คุณสามารถใช้รหัสนี้เป็นขั้นตอนแรกในไฟล์ของคุณที่จัดการคำขอ:

// Allow from any origin
if(isset($_SERVER["HTTP_ORIGIN"]))
{
    // You can decide if the origin in $_SERVER['HTTP_ORIGIN'] is something you want to allow, or as we do here, just allow all
    header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
}
else
{
    //No HTTP_ORIGIN set, so we allow any. You can disallow if needed here
    header("Access-Control-Allow-Origin: *");
}

header("Access-Control-Allow-Credentials: true");
header("Access-Control-Max-Age: 600");    // cache for 10 minutes

if($_SERVER["REQUEST_METHOD"] == "OPTIONS")
{
    if (isset($_SERVER["HTTP_ACCESS_CONTROL_REQUEST_METHOD"]))
        header("Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE, PUT"); //Make sure you remove those you do not want to support

    if (isset($_SERVER["HTTP_ACCESS_CONTROL_REQUEST_HEADERS"]))
        header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");

    //Just exit with 200 OK with the above headers for OPTIONS method
    exit(0);
}
//From here, handle the request as it is ok

8

CORS อาจกลายเป็นปวดหัวหากเราไม่เข้าใจการทำงานของมันอย่างถูกต้อง ฉันใช้มันใน PHP และทำงานได้โดยไม่มีปัญหา อ้างอิงที่นี่

header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Credentials: true");
header("Access-Control-Max-Age: 1000");
header("Access-Control-Allow-Headers: X-Requested-With, Content-Type, Origin, Cache-Control, Pragma, Authorization, Accept, Accept-Encoding");
header("Access-Control-Allow-Methods: PUT, POST, GET, OPTIONS, DELETE");

7

รหัสมากนี้ทำงานได้สำหรับฉันเมื่อใช้ angular 4 เป็นฝั่งไคลเอ็นต์และ PHP เป็นฝั่งเซิร์ฟเวอร์

header("Access-Control-Allow-Origin: *");

3

สิ่งนี้น่าจะใช้ได้

header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: X-Requested-With, Content-Type, Origin, Cache-Control, Pragma, Authorization, Accept, Accept-Encoding");

0

เพิ่มรหัสนี้ใน. htaccess

เพิ่มคีย์การรับรองความถูกต้องที่กำหนดเองในส่วนหัวเช่น app_key, auth_key..etc

Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Headers: "customKey1,customKey2, headers, Origin, X-Requested-With, Content-Type, Accept, Authorization"

-1

ใน Windows ให้วางคำสั่งนี้ในหน้าต่างทำงานเพื่อทดสอบโค้ด

chrome.exe --user-data-dir = "C: / เซสชัน Chrome dev" - ปิดการใช้งาน - ความปลอดภัยของเว็บ


การปิดใช้งานความปลอดภัยบนเว็บของเบราว์เซอร์ของคุณเป็นความคิดที่แย่มาก
Machavity
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.