Tiêu đề yêu cầu nguồn gốc chéo (CORS) với các tiêu đề PHP


146

Tôi có một tập lệnh PHP đơn giản mà tôi đang thử yêu cầu CORS tên miền chéo:

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

Tuy nhiên, tôi vẫn nhận được lỗi:

Trường tiêu đề yêu cầu X-Requested-Withkhông được cho phép bởiAccess-Control-Allow-Headers

Bất cứ điều gì tôi đang thiếu?

Câu trả lời:


59

Access-Control-Allow-Headerskhông cho phép *như giá trị được chấp nhận, xem Tài liệu Mozilla tại đây .

Thay vì dấu hoa thị, bạn nên gửi các tiêu đề được chấp nhận (đầu tiên X-Requested-Withlà lỗi nói).


289

Xử lý các yêu cầu CORS đúng cách là một chút liên quan nhiều hơn. Đây là một chức năng sẽ đáp ứng đầy đủ hơn (và đúng).

/**
 *  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
Lưu ý rằng việc gửi lại giá trị Nguồn gốc HTTP dưới dạng nguồn gốc được phép sẽ cho phép mọi người gửi yêu cầu cho bạn bằng cookie, do đó có khả năng đánh cắp phiên từ người dùng đã đăng nhập vào trang web của bạn sau đó xem trang của kẻ tấn công. Bạn có thể muốn gửi '*' (sẽ không cho phép cookie do đó ngăn chặn hành vi ăn cắp phiên) hoặc các tên miền cụ thể mà bạn muốn trang web hoạt động.
Jules

1
Đã đồng ý. Trong thực tế, có lẽ bạn sẽ không cho phép bất kỳ tên miền cũ nào sử dụng dịch vụ CORS của mình, bạn sẽ giới hạn nó ở một số bộ mà bạn quyết định tin tưởng.
slashingweapon

FYI, giải pháp này chỉ hiệu quả với tôi Linux server, IISvì một số lý do chỉ không hoạt động, tôi không biết liệu nó có phải là lưu trữ của tôi hay không, nó không phù hợp choIIS
ncubica

1
Cảm ơn bạn! Phải đánh dấu câu trả lời này. Quá tệ, chúng tôi không thể đánh dấu đây là một câu trả lời mới
Ascherer

1
Điều duy nhất thực sự hoạt động! .. Chỉ cần thay đổi Kiểm soát truy cập-Cho phép-Xuất xứ: * ĐẾN Kiểm soát truy cập-Cho phép-Xuất xứ: {$ _SERVER ['HTTP_ORIGIN']}
Renan Franca

60

Tôi đã gặp lỗi tương tự và đã sửa nó với đoạn PHP sau trong tập lệnh back-end của tôi:

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

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

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

35

Nhiều mô tả trên internet không đề cập đến việc chỉ định Access-Control-Allow-Originlà không đủ. Đây là một ví dụ hoàn chỉnh phù hợp với tôi:

<?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
Vui lòng giải thích tại sao nó không đủ và ví dụ tối thiểu đủ.
Halfpastfour.am

Thật không may, tôi không nhớ chính xác và bây giờ tôi không có thời gian để điều tra lại, nhưng, như tôi nhớ, có một số giả định cơ bản từ phía máy chủ web / trình duyệt khiến nó không hoạt động. Đây là mã tối thiểu làm việc cho tôi.
Csongor Halmai

24

Tôi chỉ đơn giản quản lý để có được dropzone và các plugin khác để làm việc với bản sửa lỗi này (angularjs + php backend)

 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');

thêm phần này vào upload.php của bạn hoặc nơi bạn sẽ gửi yêu cầu của mình (ví dụ: nếu bạn có upload.html và bạn cần đính kèm các tệp vào upload.php, sau đó sao chép và dán 4 dòng này). Ngoài ra, nếu bạn đang sử dụng plugin / addons CORS trong chrome / mozilla, hãy đảm bảo bật chúng nhiều lần, để CORS được bật


15

Nếu bạn muốn tạo một dịch vụ CORS từ PHP, bạn có thể sử dụng mã này làm bước đầu tiên trong tệp xử lý các yêu cầu:

// 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 có thể trở thành một vấn đề đau đầu, nếu chúng ta không hiểu chính xác chức năng của nó. Tôi sử dụng chúng trong PHP và chúng hoạt động mà không gặp vấn đề gì. tham khảo tại đây

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

Phần lớn mã này hoạt động với tôi khi sử dụng angular 4 làm phía máy khách và PHP làm phía máy chủ.

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

3

cái này nên hoạt động

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

0

thêm mã này vào .htaccess

thêm khóa xác thực tùy chỉnh trong tiêu đề như 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

Trong Windows, dán lệnh này khi chạy cửa sổ chỉ để kiểm tra mã

chrome.exe --user-data-dir = "C: / Chrome dev session" --disable-web-security


Vô hiệu hóa bảo mật web của trình duyệt của bạn, thậm chí tạm thời, là một ý tưởng tồi tệ
Machavity
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.