dayan
dayan

Reputation: 402

Nginx PHP API CORS

I'm developing the SPA with VueJS which should operate with PHP API/Nginx on the remote domain. Of course I've faced the CORS problem.

Here is the recent Nginx config file:

 location / {

                add_header 'Access-Control-Allow-Origin' '*';
                add_header 'Access-Control-Allow-Credentials' 'true';
                add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE, HEAD';
                add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,some_my_tokens';

            if ($request_method = 'OPTIONS') {
                add_header 'Access-Control-Max-Age' '1728000';
                add_header 'Access-Control-Allow-Credentials' 'true';
                add_header 'Access-Control-Allow-Headers' 'Origin,Content-Type,Accept,Authorization,some_my_tokens';
                add_header 'Content-Type' 'text/plain; charset=UTF-8';
                add_header 'Content-Length' '0';
                return 204;
            }

            try_files $uri $uri/ /index.php?$args;

        }

I'm still getting Errors "No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://remote_host:8080' is therefore not allowed access.".

Please help.

Upvotes: 2

Views: 6510

Answers (4)

AamirR
AamirR

Reputation: 12218

In my case, when our backend was sending an error response, for example in PHP header('HTTP', ERROR_CODE), was resulting in CORS headers missing from response.

Adding the always parameter to these CORS headers fixed the issue:

add_header Access-Control-Allow-Origin $http_origin always;

As the docs states about add_header directive

Adds the specified field to a response header provided that the response code equals 200, 201 (1.3.10), 204, 206, 301, 302, 303, 304, 307 (1.1.16, 1.0.13), or 308 (1.13.0).

and docs says about always parameter

If the always parameter is specified (1.7.5), the header field will be added regardless of the response code.

Upvotes: 3

jmng
jmng

Reputation: 2568

I'd suggest using more_set_headers on nginx.conf instead of add_header, for example:

   location / {

            more_set_headers 'Access-Control-Allow-Origin' '*';
            more_set_headers 'Access-Control-Allow-Credentials' 'true';
            more_set_headers 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE, HEAD';
            more_set_headers 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,some_my_tokens';

        if ($request_method = 'OPTIONS') {
            more_set_headers 'Access-Control-Max-Age' '1728000';
            more_set_headers 'Access-Control-Allow-Credentials' 'true';
            more_set_headers 'Access-Control-Allow-Headers' 'Origin,Content-Type,Accept,Authorization,some_my_tokens';
            more_set_headers 'Content-Type' 'text/plain; charset=UTF-8';
            more_set_headers 'Content-Length' '0';
            return 204;
        }

        try_files $uri $uri/ /index.php?$args;

    }

The more_set_headers directive is part of the HttpHeadersMore module which is included in the nginx-extras flavor of nginx, you can install it on ubuntu 16 by doing:

sudo apt-get install nginx-extras

Upvotes: 1

miknik
miknik

Reputation: 5951

The reason it's saying No 'Access-Control-Allow-Origin' header is present on the requested resource is because.....

wait for it....

no 'Access-Control-Allow-Origin' header is present on the requested resource.

You have this directive in your location block:

add_header 'Access-Control-Allow-Origin' '*';

But then you have an if condition for OPTIONS requests, and within that level you don't have an Access-Control-Allow-Origin header.

From the docs

There could be several add_header directives. These directives are inherited from the previous level if and only if there are no add_header directives defined on the current level.

So your OPTIONS preflight will be missing the header.

Upvotes: 1

Hiren Ghodasara
Hiren Ghodasara

Reputation: 336

Add below code in your index.php

if (isset($_SERVER['HTTP_ORIGIN'])) {
    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'])) {
        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);
}

Upvotes: 5

Related Questions