Nginx PHP API CORS

Posted

技术标签:

【中文标题】Nginx PHP API CORS【英文标题】: 【发布时间】:2019-02-27 23:34:20 【问题描述】:

我正在使用 VueJS 开发 SPA,它应该在远程域上使用 php API/nginx 运行。当然,我遇到了 CORS 问题。

这是最近的 Nginx 配置文件:

 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;

        

我仍然收到错误消息“请求的资源上没有 'Access-Control-Allow-Origin' 标头。因此不允许访问 Origin 'http://remote_host:8080'。”。

请帮忙。

【问题讨论】:

【参考方案1】:

我建议在 nginx.conf 上使用more_set_headers 而不是add_header,例如:

   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;

    

more_set_headers 指令是 HttpHeadersMore 模块的一部分,该模块包含在 nginx 的 nginx-extras flavor 中,您可以通过以下操作将其安装在 ubuntu 16 上:

sudo apt-get install nginx-extras

【讨论】:

【参考方案2】:

之所以说No 'Access-Control-Allow-Origin' header is present on the requested resource是因为.....

等等……

请求的资源上不存在“Access-Control-Allow-Origin”标头。

您的位置块中有此指令:

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

但是对于 OPTIONS 请求,您有一个 if 条件,并且在该级别内您没有 Access-Control-Allow-Origin 标头。

来自the docs

可能有多个 add_header 指令。这些指令是 从上一层继承当且仅当没有 在当前级别上定义的 add_header 指令。

所以您的OPTIONS 预检将丢失标题。

【讨论】:

【参考方案3】:

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

【讨论】:

PHP hack 确实有效。仅使用 nginx 配置解决它的任何选项? @dayan,你可以通过 nginx.conf 来做,看看我的回答

以上是关于Nginx PHP API CORS的主要内容,如果未能解决你的问题,请参考以下文章

PHP API - Nginx 给了我无效的数据类型标头

Nginx PHP API CORS

如果正在进行流式下载,Nginx PHP-FPM无法提供请求

Nginx反向代理 Laravel获取真实IP地址(PHP)

nginx配置 接口状态200,但是PHP无返回数据,php服务

nginx支持pathinfo