Heim  >  Fragen und Antworten  >  Hauptteil

CORS-Problem in PHP: Antwort von Preflight-Anfrage wird nicht weitergeleitet. erlaubte Quellen

Ich weiß also, dass es da draußen viele CORS-Beiträge gibt, und ich füge sie nur hinzu, aber ich kann keine Antworten finden, die mir helfen könnten. Also erstelle ich eine Angular 4-Anwendung, die auf meiner PHP-API basiert. Funktioniert lokal ohne Probleme. Wenn ich es auf die Domäne mit der API unter app.example.com 的应用程序和位于 api.example.com werfe, kann ich mich nicht anmelden, da ich die folgende Fehlermeldung erhalte:

XMLHttpRequest kann http://api.example.com/Account/Login nicht laden. Antwort auf Preflight-Anfrage fehlgeschlagene Zugriffskontrollprüfung: Nein Der Header „Access-Control-Allow-Origin“ ist in der Anfrage vorhanden Ressource. Daher ist die Quelle „http://app.example.com“ nicht zulässig Zugang.

Mein PHP-Code sieht so aus:

$http_origin = $_SERVER['HTTP_ORIGIN'];

$allowed_domains = array(
    'http://example.com',
    'https://example.com',
    'http://app.example.com',
    'https://app.example.com',
    'http://www.example.com',
    'https://www.example.com'
);

if (in_array(strtolower($http_origin), $allowed_domains))
{  
    // header("Access-Control-Allow-Origin: *");
    header("Access-Control-Allow-Origin: $http_origin");
    header('Access-Control-Allow-Credentials: true');
    header('Access-Control-Max-Age: 86400');
}

// Access-Control headers are received during OPTIONS requests
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
        header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
        header("Access-Control-Allow-Headers: Authorization, Content-Type,Accept, Origin");
    exit(0);
}

Mein Angular-Beitrag sieht so aus:

public login(login: Login): Observable<LoginResponse> {
    let headers = new Headers();
    headers.append('Content-Type', 'application/x-www-form-urlencoded');
    headers.append('Authorization', 'Basic ' + btoa(login.Username + ':' + login.Password));
    return  this.http.post(this.apiBaseUrl + '/Account/Login', "grant_type=client_credentials", { headers: headers })
        .map(response => {
            // code
        });
}

Wenn ich die Anfrage über Postman leite (dies wirkt sich nicht auf CORS aus), erhalte ich:

{ "error": "invalid_client", "error_description": "Client credentials were not found in the headers or body" }

Ich habe versucht, den Ursprung auf „*“ zu setzen, nur um zu testen, ob dies der Kern des Problems ist, aber es ist immer noch auf die gleiche Weise fehlgeschlagen.

Bearbeiten Ich aktualisiere es einfach mit den unten stehenden Informationen. Das Ändern der Groß-/Kleinschreibung im Header hat keine Auswirkung, und das Herausziehen des Codes aus der if-Anweisung hat ebenfalls keine Auswirkung.

Ich habe PHP debuggt, indem ich meiner Live-App gesagt habe, sie solle zur lokalen API gehen, und PHP funktioniert wie erwartet. Es legt den Header fest und fügt ihn in jede if-Anweisung ein.

Aufnahme 2 bearbeiten Ich brauche wirklich Hilfe und wenn jemand eine Idee hat, wäre ich sehr dankbar.

Aufnahme 3 bearbeiten Wenn ich alle Header-Sachen in .htaccess statt in PHP einstelle, kann ich passieren. Allerdings bleibe ich jetzt bei dem oben aufgeführten Fehler hängen, der der Fehler ist, den ich immer bekomme, wenn ich Postman verwende, aber jetzt, wenn ich die eigentliche Website verwende.

{"error":"invalid_client","error_description":"在标头或正文中找不到客户端凭据"}

Meine Antwortheader sehen so aus

Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:authorization, content-type, accept, origin
Access-Control-Allow-Methods:GET, POST, OPTIONS
Access-Control-Allow-Origin:*

Sobald es funktioniert, ändere ich es von * in nur meine Domain. Aber jetzt belasse ich es als *.

Mein Header auf Anfrage.

P粉564192131P粉564192131338 Tage vor631

Antworte allen(2)Ich werde antworten

  • P粉952365143

    P粉9523651432023-10-22 00:47:32

    在我的类似案例中,Angular 前端和 Php 后端帮助了下面的代码。首先我发送一个标头:

    header("Access-Control-Allow-Origin: http://localhost:4200");   
    header("Content-Type: application/json; charset=UTF-8");    
    header("Access-Control-Allow-Methods: POST, DELETE, OPTIONS");    
    header("Access-Control-Max-Age: 3600");    
    header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");

    在他们之后,我可以忽略选项请求:

    if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {    
       return 0;    
    }

    这种方法帮助我处理 Angular 中的“post”和“delete”嵌入请求方法。

    Antwort
    0
  • P粉860370921

    P粉8603709212023-10-22 00:29:25

    好吧,我最近遇到了类似的问题,我只在后端解决了所有问题,没有 .htaccess 的东西。

    当浏览器发送跨服务器请求时,它首先发送一个 OPTIONS 请求以确保其有效并且可以发送“真实”请求。 当它从 OPTIONS 获得正确且有效的响应后,才会发送“真正的”请求。

    现在,对于后端的两个请求,您需要确保返回正确的标头:content-type、allow-origin、allow-headers 等...

    确保在后端的 OPTIONS 请求中,应用程序返回标头并返回响应,而不是继续应用程序的完整流程。

    在“真实”请求中,您应该返回正确的标头和常规响应正文。

    示例:

    //The Response object
        $res = $app->response;
    
        $res->headers->set('Content-Type', 'application/json');
        $res->headers->set('Access-Control-Allow-Origin', 'http://example.com');
        $res->headers->set('Access-Control-Allow-Credentials', 'true');
        $res->headers->set('Access-Control-Max-Age', '60');
        $res->headers->set('Access-Control-Allow-Headers', 'AccountKey,x-requested-with, Content-Type, origin, authorization, accept, client-security-token, host, date, cookie, cookie2');
        $res->headers->set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
    
        if ( ! $req->isOptions()) {
            // this continues the normal flow of the app, and will return the proper body
            $this->next->call();
        } else {
            //stops the app, and sends the response
            return $res;
        }

    要记住的事情:

    • 如果您使用:“Access-Control-Allow-Credentials”= true 确保“Access-Control-Allow-Origin”不是“*”,它必须设置正确的域! (这里流了很多血:/)

    • 定义您将在“Access-Control-Allow-Headers”中获得的允许标头 如果您不定义它们,请求将失败

    • 如果您使用“Authorization: Bearer”,那么“Access-Control-Allow-Headers”也应包含“Authorization”,否则请求将失败

    Antwort
    0
  • StornierenAntwort