首页 文章

CORS:PHP:对预检请求的响应没有通过 . 允许来源

提问于
浏览
6

所以我知道's a lot of CORS posts out there, and I'只是添加它们,但我可以't find any with answers that help me out. So I' m构建一个依赖于我的php api的角度4应用程序 . 在本地工作很好,我在应用程序位于 app.example.com 并在 api.example.com 处的api将其投放到域上的那一刻,我无法通过我的登录,因为我收到以下错误:

XMLHttpRequest无法加载http://api.example.com/Account/Login . 对预检请求的响应未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”标头 . 因此,不允许来源“http://app.example.com”访问 .

我的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" }

I 've tried setting origin to ' * '只是为了测试并查看这是否是问题的核心,它仍然以同样的方式失败 .

Edit 只需根据以下信息进行更新 . 更改 Headers 中的大小写无效,将代码从if语句中拉出来没有任何效果 .

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

Edit take 2 我真的可以在这个上使用一些帮助,如果有人有任何想法,我真的很感激 .

Edit take 3 如果我在我的.htaccess而不是我的php中设置所有 Headers 内容,它就可以让我通过 . 但是,现在我在使用实际网站时'm stuck on the error listed above that I always get when using postman, however now it' .

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

我的回复 Headers 是这样的

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

一旦我开始工作,我就会将它从更改为仅我的域名 . 但是现在我将它留作 .

My headers as requested.

Headers for failed request

2 回答

  • 1

    好的我最近有类似的问题,我只在后端方面解决了所有问题,没有.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”中获得的允许标头,如果您不定义它们,请求将失败

  • 0

    我在下面添加了php,它解决了我的问题 .

    header("Access-Control-Allow-Origin: *");
    
    header("Access-Control-Allow-Headers: Content-Type, origin");
    

相关问题