php - CORS:PHP:对预检请求的响应未通过。我允许原产地

标签 php angular cors preflight

所以我知道那里有很多 CORS 帖子,我只是在添加它们,但我找不到任何可以帮助我解决问题的答案。所以我正在构建一个依赖于我的 php api 的 angular 4 应用程序。在本地工作没问题,当我使用 app.example.com 上的应用程序和 api.example.com 上的 api 将它扔到域上时,我可以' 通过我的登录,因为我收到以下错误:

XMLHttpRequest cannot load http://api.example.com/Account/Login. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://app.example.com' is therefore not allowed access.

我的 php 代码如下所示:

$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);
}

我的 Angular 帖子看起来像这样:

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

如果我通过 postman 运行请求,这不会影响 CORS,我会得到:

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

我已经尝试将 origin 设置为 '*' 只是为了测试并查看这是否是问题的核心,但它仍然以同样的方式失败。

编辑 只是从下面的信息更新。更改 header 中的大小写没有任何效果,并且将代码从其 if 语句中拉出也没有任何效果。

我通过告诉我的实时应用程序转到我的本地 api 来调试 php,并且 php 正在按预期工作。它正在设置 header 并将其放入每个 if 语句中。

编辑 take 2 我真的可以在这方面得到一些帮助,如果有人有任何想法,我将不胜感激。

编辑 take 3 如果我在我的 .htaccess 而不是我的 php 中设置所有 header 内容,它会让我通过。但是,现在我陷入了上面列出的错误,我在使用 postman 时总是遇到这种错误,但是现在是在使用实际站点时。

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

我的响应头是这样的

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:*

一旦我开始工作,我会将其从 * 更改为仅我的域。但现在我将其保留为 *。

我的请求头。

Headers for failed request

最佳答案

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

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

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

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

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

例子:

    //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”中获得的允许 header 如果您不定义它们,请求将失败

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

关于php - CORS:PHP:对预检请求的响应未通过。我允许原产地,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44479681/

相关文章:

LAN 中的 PHP 和服务器到服务器通信

javascript - 如果 json_encode 包含数据库查询中的字符,则 JavaScript 上的条件

javascript - 如何修复响应 : {type: "cors"} when trying to create payment through paypal api

django - vue.js 和 django 中的访问控制允许来源问题

javascript - (PHP) 克隆按钮上的按钮单击计数器

php - 如何检测浏览器/选项卡是否关闭

angular - 如何将 JSON 映射到具有计算属性的 TypeScript 对象

Angular 表单验证突出问题

google-maps - 使用 googlemaps javascript API 时,Typescript 错误在 ionic2 中找不到名称 'google'

c# - 仅在启用 cors 时才响应 asp.net web api POST 请求的 400