Cross-Origin Request Headers (CORS) dengan header PHP

146

Saya punya skrip PHP sederhana yang sedang saya coba permintaan lintas-domain CORS:

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

Namun saya masih mendapatkan kesalahan:

Bidang tajuk permintaan X-Requested-Withtidak diizinkan olehAccess-Control-Allow-Headers

Ada yang hilang?

Machavity
sumber

Jawaban:

59

Access-Control-Allow-Headerstidak mengizinkan *sebagai nilai yang diterima, lihat Dokumentasi Mozilla di sini .

Alih-alih tanda bintang, Anda harus mengirim tajuk yang diterima (pertama X-Requested-Withseperti kata kesalahan).

KARASZI István
sumber
289

Menangani permintaan CORS dengan benar sedikit lebih terlibat. Berikut adalah fungsi yang akan merespons lebih lengkap (dan semestinya).

/**
 *  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!";
}
slashingweapon
sumber
32
Perhatikan bahwa mengirim kembali nilai Asal HTTP sebagai asal yang diizinkan akan memungkinkan siapa saja untuk mengirim permintaan kepada Anda dengan cookie, sehingga berpotensi mencuri sesi dari pengguna yang masuk ke situs Anda kemudian melihat halaman penyerang. Anda ingin mengirim '*' (yang akan melarang cookie sehingga mencegah pencurian sesi) atau domain spesifik tempat Anda ingin situs berfungsi.
Jules
1
Sepakat. Dalam praktiknya Anda mungkin tidak akan mengizinkan sembarang domain lama untuk menggunakan layanan CORS Anda, Anda akan membatasi untuk beberapa set yang Anda memutuskan untuk percaya.
slashingweapon
FYI, solusi ini hanya bekerja untuk saya dalam Linux server, IISuntuk beberapa alasan tidak berfungsi, saya tidak tahu apakah ini hosting saya atau hanya itu tidak cocok untukIIS
ncubica
1
Terima kasih! Harus menandai jawaban ini. Sayang sekali kami tidak dapat menandai ini sebagai jawaban baru
Ascherer
1
Satu-satunya yang benar-benar berfungsi! .. Ubah saja Access-Control-Allow-Origin: * TO Access-Control-Allow-Origin: {$ _SERVER ['HTTP_ORIGIN']}
Renan Franca
60

Saya mendapatkan kesalahan yang sama, dan memperbaikinya dengan PHP berikut di skrip back-end saya:

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

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

header("Access-Control-Allow-Headers: X-Requested-With");
Fiach Reid
sumber
35

Banyak deskripsi di internet tidak menyebutkan bahwa Access-Control-Allow-Origintidak cukup. Berikut ini adalah contoh lengkap yang berfungsi untuk saya:

<?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);
Csongor Halmai
sumber
1
Tolong jelaskan mengapa itu tidak cukup dan contoh minimal apa yang cukup.
halfpastfour.am
Sayangnya, saya tidak ingat persis dan saya tidak punya waktu sekarang untuk menyelidikinya lagi tetapi, sebanyak yang saya ingat, ada beberapa asumsi dasar dari sisi browser / peramban yang membuatnya tidak berfungsi. Ini adalah kode minimal yang bekerja untuk saya.
Csongor Halmai
24

Saya hanya berhasil mendapatkan dropzone dan plugin lain untuk bekerja dengan perbaikan ini (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');

tambahkan ini di upload.php Anda atau ke mana Anda akan mengirim permintaan Anda (misalnya jika Anda telah mengunggah.html dan Anda harus melampirkan file-file itu ke upload.php, lalu salin dan tempel 4 baris ini). Juga jika Anda menggunakan plugin / add-on CORS di chrome / mozilla pastikan untuk mengaktifkannya lebih dari satu kali, agar CORS diaktifkan.

Fedeco
sumber
15

Jika Anda ingin membuat layanan CORS dari PHP, Anda dapat menggunakan kode ini sebagai langkah pertama dalam file Anda yang menangani permintaan:

// 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
Finn Johansen
sumber
8

CORS dapat menjadi sakit kepala, jika kita tidak memahami fungsinya dengan benar. Saya menggunakannya dalam PHP dan mereka bekerja tanpa masalah. referensi di sini

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");
shades3002
sumber
7

Banyak kode ini bekerja untuk saya ketika menggunakan sudut 4 sebagai sisi klien dan PHP sebagai sisi server.

header("Access-Control-Allow-Origin: *");
Labib Hussain
sumber
3

ini seharusnya bekerja

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

tambahkan kode ini dalam .htaccess

tambahkan kunci autentikasi khusus di header seperti 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"
Rakyesh Kadadas
sumber
-1

Di Windows, rekatkan perintah ini dalam menjalankan jendela hanya untuk sementara waktu untuk menguji kode

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

Fazil Raza
sumber
Menonaktifkan keamanan web browser Anda, bahkan untuk sementara, adalah ide yang buruk
Machavity