Home  >  Q&A  >  body text

CORS: PHP: Response to preflight request failed. I allow origin

<p>So I know there are a lot of CORS posts out there and I'm just adding them but I can't find any answers that can help me. So I'm building an Angular 4 application that relies on my php api. Works locally no problem, when I throw it on the domain with the app at <code>app.example.com</code> and the api at <code>api.example.com</code> I am unable to pass my login as I get the following error: </p> <blockquote> <p>XMLHttpRequest cannot load http://api.example.com/Account/Login. Response to preflight request failed access control check: No 'Access-Control-Allow-Origin' header present in request resource. So source "http://app.example.com" is not allowed access.</p> </blockquote> <p>我的 php 代码如下所示:</p> <pre class="brush:php;toolbar:false;">$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); }</pre> <p>我的 Angular 帖子如下所示:</p> <pre class="brush:php;toolbar:false;">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 }); }</pre> <p>如果我通过邮递员运行请求(这不会影响 CORS),我会得到:</p> <pre class="brush:php;toolbar:false;">{ "error": "invalid_client", "error_description": "Client credentials were not found in the headers or body" }</pre> <p>我尝试将 origin 设置为 '<code>*</code>' 只是为了测试并查看这是否是问题的核心,但它仍然以同样的方式失败。</p> <p><strong><em>编辑</em></strong> 只是根据以下信息进行更新。更改标头中的大小写没有任何效果,并且从 if 语句中提取代码也没有任何效果。</p> <p>我通过告诉我的实时应用程序转到本地 api 来调试 php,并且 php 正在按预期工作。它设置标头并将其放入每个 if 语句中。</p> <p><strong><em>编辑镜头 2</em></strong> 我确实需要一些帮助,如果有人有任何想法,我将非常感激。</p> <p><strong><em>Edit Shot 3</em></strong> If I set all the header stuff in .htaccess instead of php it lets me pass. However, now I'm stuck with the error listed above, which is the error I always get when using Postman, but now when using the actual website. </p> <p><code>{"error":"invalid_client","error_description":"Client credentials not found in header or body"}</code></p> <p>My response headers look like this</p> <pre class="brush:php;toolbar:false;">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:*</pre> <p>Once it's working I'll change it from * to just my domain. But now I leave it as *. </p> <p><strong>My header upon request. </strong></p>
P粉642920522P粉642920522444 days ago631

reply all(2)I'll reply

  • P粉502608799

    P粉5026087992023-08-25 17:38:47

    In my similar case, Angular frontend and Php backend helped with the code below. First I send a header:

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

    After them I can ignore option requests:

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

    This approach helped me handle "post" and "delete" embedded request methods in Angular.

    reply
    0
  • P粉316890884

    P粉3168908842023-08-25 16:25:07

    Well, I had a similar problem recently and I solved it all on the backend only, without the .htaccess stuff.

    When the browser sends a cross-server request, it first sends an OPTIONS request to ensure that it is valid and that a "real" request can be sent. The "real" request is sent when it gets a correct and valid response from OPTIONS.

    Now, for both requests to the backend, you need to make sure the correct headers are returned: content-type, allow-origin, allow-headers, etc...

    Ensure that in the OPTIONS request on the backend, the application returns the header and returns the response instead of continuing the full flow of the application.

    In a "real" request you should return the correct headers and regular response body.

    Example:

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

    Things to remember:

    • If you use: "Access-Control-Allow-Credentials" = true Make sure "Access-Control-Allow-Origin" is not "*", it must be set to the correct domain! (A lot of blood was shed here :/)

    • Define the allow headers you will get in "Access-Control-Allow-Headers" If you don't define them, the request will fail

    • If you use "Authorization: Bearer", then "Access-Control-Allow-Headers" should also contain "Authorization", otherwise the request will fail

    reply
    0
  • Cancelreply