繁体   English   中英

修复'Access-Control-Allow-Origin'标头在NGINX中包含多个值错误

[英]Fixing the 'Access-Control-Allow-Origin' header contains multiple values error in NGINX

我正在建立一个Wordpress网站(例如http://api.example.com ),以便从另一个静态的HTML / JS网站(例如https://test.example.com )中获取API。

这两个网站都托管在Nginx服务器上,每个网站都配置了一个conf文件,并且可以自行运行。 nginx -t没有产生任何错误,我可以按预期完全访问这两个网站。

不幸的是我遇到了CORS的问题。 当试图读取媒体(图片,视频)内容api.example.comtest.example.com产生在浏览器控制台以下错误:

Access to XMLHttpRequest at 
'https://api.example.com/wp-json/custom-post/v1/some-data/' 
from origin 'https://test.example.com' has been blocked by CORS policy: 

The 'Access-Control-Allow-Origin' header contains multiple values
'https://test.example.com, https://test.example.com', 
but only one is allowed.

此外,在Chrome上,此错误之后是CORB错误( Cross-Origin Read Blocking (CORB) blocked cross-origin response https://api.example.com/wp-json with MIME type application/json. )。

我注意到在浏览器中检查请求标头时,这些属性的冗余值:

Access-Control-Allow-Credentials: true, true
Access-Control-Allow-Origin: https://test.example.com, https://test.example.com

感觉到某处可能存在冗余的Access-Control-Allow-Origin ,我在nginx.conf文件中查找了它,并且在sites-enabledsites-enabled所有conf文件中都无济于事。 我也查看了Wordpress应用程序的源代码,使用了包含的插件,用于注入此标头。 没有人找到。

最后,我试图删除api.example.com.conf中的api.example.com.conf添加Access-Control-Allow-Origin标头 - 它产生纯粹而简单的api.example.com.conf No 'Access-Control-Allow-Origin' header is present on the requested resource浏览器控制台中媒体内容的No 'Access-Control-Allow-Origin' header is present on the requested resource错误。 有趣的是,它不再产生JSON的CORB错误, test.example.com能够从JSON文件中读取文本内容。

这是api.example.com.conf文件的内容:

server {
    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

    root /var/www/example.com/backend;
    server_name api.example.com;
    access_log /var/log/nginx/unicorn_access.log;
    error_log /var/log/nginx/unicorn_error.log;

    charset                     utf-8;
    gzip                        off;

    # Set CORS policy
    set $cors_origin            "";
    set $cors_cred              "";
    set $cors_header            "";
    set $cors_method            "";

    if ($http_origin ~ '^https?:\/\/(localhost|test.example\.com)$') {
        set $cors_origin        $http_origin;
        set $cors_cred          true;
        set $cors_header        $http_access_control_request_headers;
        set $cors_method        $http_access_control_request_method;
    }

    add_header Access-Control-Allow-Origin      $cors_origin;
    add_header Access-Control-Allow-Credentials $cors_cred;
    add_header Access-Control-Allow-Headers     $cors_header;
    add_header Access-Control-Allow-Methods     $cors_method;

    location / {
        index                   index.php index.html;
        try_files               $uri $uri/ /index.php?$args;
    }

    client_max_body_size        50m;

    # Add trailing slash to */wp-admin requests.
    rewrite /wp-admin$ $scheme://$host$uri/ permanent;

    # Prevents hidden files (beginning with a period) from being served
    location ~ /\. {
        access_log              off;
        log_not_found           off;
        deny                    all;
    }

    # Send 'expires' headers and turn off 404 logging
    location ~* ^.+.(xml|ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|css|rss|atom|js|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ {
        access_log              off;
        log_not_found           off;
        expires                 max;
    }

    # Pass all .php files onto a php-fpm or php-cgi server
    location ~ \.php$ {
        try_files               $uri =404;
        include                 /etc/nginx/fastcgi_params;
        fastcgi_read_timeout    3600s;
        fastcgi_buffer_size     128k;
        fastcgi_buffers         4 128k;
        fastcgi_param           SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_pass            unix:/run/php/php7.2-fpm.sock;
        fastcgi_index           index.php;
    }

    # Robots
    location = /robots.txt {
        allow all;
        log_not_found off;
        access_log off;
    }

    # Restrictions
    location ~* /(?:uploads|files)/.*\.php$ {
        deny all;
    }
}

我希望test.example.com消费从任何内容api.example.com ,但我不能这么完全做到。

谢谢你的帮助!

这是由于rest_send_cors_headers将REST API挂钩过滤到rest_pre_serve_request 它发送了带有API请求的 CORS头文件。

可以通过以下操作关闭它:

add_action('rest_api_init', function() {
    remove_filter('rest_pre_serve_request', 'rest_send_cors_headers');
}, 15);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM