Ursprungsübergreifende Anforderungsheader (CORS) mit PHP-Headern

146

Ich habe ein einfaches PHP-Skript, mit dem ich eine domänenübergreifende CORS-Anfrage versuche:

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

Trotzdem bekomme ich immer noch den Fehler:

Anforderungsheaderfeld X-Requested-Withist von nicht zulässigAccess-Control-Allow-Headers

Fehlt mir etwas?

Machavity
quelle

Antworten:

59

Access-Control-Allow-Headerserlaubt nicht *als akzeptierten Wert, siehe die Mozilla-Dokumentation hier .

Anstelle des Sternchens sollten Sie die akzeptierten Header senden (zuerst, X-Requested-Withwie der Fehler sagt).

KARASZI István
quelle
289

Der richtige Umgang mit CORS-Anfragen ist etwas komplizierter. Hier ist eine Funktion, die vollständiger (und korrekter) reagiert.

/**
 *  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!";
}
Hiebwaffe
quelle
32
Beachten Sie, dass das Zurücksenden des HTTP-Ursprungswerts als zulässiger Ursprung es jedem ermöglicht, Anforderungen mit Cookies an Sie zu senden, wodurch möglicherweise eine Sitzung von einem Benutzer gestohlen wird, der sich auf Ihrer Website angemeldet und dann die Seite eines Angreifers angezeigt hat. Sie möchten entweder '*' senden (wodurch Cookies nicht zugelassen werden, wodurch Sitzungsdiebstahl verhindert wird) oder die spezifischen Domains, für die die Site funktionieren soll.
Jules
1
Einverstanden. In der Praxis würden Sie wahrscheinlich nicht zulassen, dass nur eine alte Domain Ihren CORS-Dienst verwendet. Sie würden ihn auf einen Satz beschränken, dem Sie vertrauen möchten.
Hiebwaffe
Zu Ihrer Information, diese Lösung funktionierte nur für mich in einem Linux server, in IISirgendeinem Grund einfach nicht funktioniert, ich weiß nicht, ob es mein Hosting ist oder einfach nicht geeignet fürIIS
ncubica
1
Danke dir! Müssen diese Antwort bookmarken. Schade, dass wir dies nicht als neue Antwort markieren können
Ascherer
1
Das einzige, was wirklich funktioniert! .. Ändern Sie einfach Access-Control-Allow-Origin: * TO Access-Control-Allow-Origin: {$ _SERVER ['HTTP_ORIGIN']}
Renan Franca
60

Ich habe den gleichen Fehler erhalten und ihn mit dem folgenden PHP in meinem Back-End-Skript behoben:

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

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

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

Viele Beschreibungen im Internet erwähnen nicht, dass die Angabe Access-Control-Allow-Originnicht ausreicht. Hier ist ein vollständiges Beispiel, das für mich funktioniert:

<?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
quelle
1
Bitte erklären , warum es nicht genug ist , und was minimal Beispiel ist genug.
halfpastfour.am
Leider erinnere ich mich nicht genau und ich habe jetzt keine Zeit, es erneut zu untersuchen, aber soweit ich mich erinnere, gab es einige grundlegende Annahmen von der Seite des Webservers / Browsers, die dazu führten, dass es nicht funktionierte. Dies war der minimale Code, der für mich funktioniert hat.
Csongor Halmai
24

Ich habe es einfach geschafft, Dropzone und andere Plugins mit diesem Fix zum Laufen zu bringen (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');

füge dies in deine upload.php ein oder wohin du deine Anfrage senden würdest (zum Beispiel wenn du upload.html hast und die Dateien an upload.php anhängen musst, dann kopiere und füge diese 4 Zeilen ein). Auch wenn Sie CORS-Plugins / Addons in Chrome / Mozilla verwenden, müssen Sie diese mehrmals umschalten, damit CORS aktiviert wird

Fedeco
quelle
15

Wenn Sie einen CORS-Dienst aus PHP erstellen möchten, können Sie diesen Code als ersten Schritt in Ihrer Datei verwenden, der die Anforderungen verarbeitet:

// 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
quelle
8

CORS kann zu Kopfschmerzen werden, wenn wir seine Funktionsweise nicht richtig verstehen. Ich benutze sie in PHP und sie funktionieren ohne Probleme. Referenz hier

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");
Schatten3002
quelle
7

So viel Code funktioniert für mich, wenn ich Angular 4 als Client-Seite und PHP als Server-Seite verwende.

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

das sollte funktionieren

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

Fügen Sie diesen Code in .htaccess hinzu

Fügen Sie im Header benutzerdefinierte Authentifizierungsschlüssel wie app_key, auth_key..etc hinzu

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
quelle
-1

Fügen Sie diesen Befehl in Windows vorerst in das Ausführungsfenster ein, um den Code zu testen

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

Fazil Raza
quelle
Es ist eine schreckliche Idee, die
Websicherheit