AJAX CORS http 请求 nginx 拒绝
Posted
技术标签:
【中文标题】AJAX CORS http 请求 nginx 拒绝【英文标题】:AJAX CORS http request nginx rejection 【发布时间】:2019-01-18 09:52:48 【问题描述】:我已经搜索了所有其他相关主题,但找不到针对我的具体问题的解决方案。
我编写了一个包含 AJAX http 请求(get 和 put)的网站。获取这些请求的服务器是 nginx 并在 debian 下运行。
只要我建议我的浏览器忽略 Allow-Access-Header 拒绝,一切都会完美运行。但是如果我不让浏览器忽略它。发生这种情况:
Failed to load http://***/api/devices/7: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://***' is therefore not allowed access.
这是我的 nginx 配置文件,它在 z-wave 基站上运行,所以所有其他配置都与此相关:
worker_processes 1;
error_log /dev/null;
events
worker_connections 1024;
http
include mime.types;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
types_hash_max_size 2048;
keepalive_timeout 65;
client_max_body_size 300M;
access_log /dev/null;
upstream hcserver
server 127.0.0.1:11111;
keepalive 15;
server
listen 80;
server_name localhost;
proxy_read_timeout 400;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
location /api/service/
rewrite ^/api/service/(.*) /services/system/$1.php;
location /api/service/backups/
rewrite ^/api/service/backups/(.*)$ /services/system/backups.php?id=$1;
location /api/
proxy_pass http://hcserver;
proxy_http_version 1.0;
proxy_set_header Connection "Keep-Alive";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_buffering off;
error_page 502 =503 /vendor/en/home/503.html;
location /
root /var/www/;
index index.html index.htm index.php;
if ($request_method = 'OPTIONS')
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
#
# Custom headers and headers various browsers *should* be OK with but aren't
#
#
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
#
# Tell client that this pre-flight info is valid for 20 days
#
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
if ($request_method = 'POST')
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
if ($request_method = 'GET')
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
location ~* \.(css|js|html)$
add_header Cache-Control "must-revalidate, max-age=0, max-age:0, no-cache, no-store";
add_header Pragma no-cache;
add_header Expires 'Fri, 01 Jan 2010 00:00:00 GMT';
ssi on;
ssi_value_length 2056;
error_page 404 /vendor/404.html;
location ~* \.sh$
proxy_pass http://127.0.0.1:8000;
location ~* \.php$
proxy_pass http://127.0.0.1:8000;
location ~* \.php\?.*
proxy_pass http://127.0.0.1:8000;
rewrite ^/vendor/icons/User(.*) /vendor/icons/userIcons/User$1;
rewrite ^/vendor/icons/rooms/User(.*) /vendor/icons/rooms/userIcons/User$1;
rewrite ^/vendor/icons/scena/User(.*) /vendor/icons/scena/userIcons/User$1;
rewrite ^/vendor/n_vicons/User(.*) /vendor/n_vicons/userIcons/User$1;
rewrite ^/vendor/data_request(.*)php(.*) /api/mobile$2;
rewrite ^/vendor/(js/)(.*) /vendor/js/$2 last;
rewrite ^/vendor/([a-z][a-z]/)(.*) /vendor/$2;
亲切的问候,请不要破解我的IP:127.0.0.1 ;)
【问题讨论】:
【参考方案1】:您的配置中的缩进有点偏离,但在我看来,您只是在 location /
块内添加了 CORS 标头。作为起点,尝试将这些标头提升到 server
块,如下所示:
server
listen 80;
server_name localhost;
add_header Access-Control-Allow-Origin $http_origin;
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range";
add_header Access-Control-Expose-Headers "Content-Length,Content-Range";
add_header Access-Control-Max-Age 1728000;
现在,这些规则将应用于此服务器的每个位置块(以及每个$request_method
)。
如果您需要特定于上下文的规则 - 例如,不同端点的不同 CORS 标头值 - 这仍然是一个很好的起点,因为它将验证包罗万象的解决方案。一旦您某些东西工作了,就可以更轻松地对规则进行小幅更改,同时进行测试以找出问题所在。
希望这会有所帮助。如果没有,更新您的问题,包括完整的curl
- 请求和响应的标头和正文 - 将非常有帮助。
【讨论】:
你是绝对正确的。我不知道,因为我以前从未配置过 nginx,现在感觉很愚蠢。还有另一个问题,因为我发送了 Access-Control-Allow-Origin '*' 不允许的 Authorization 标头 ... 很高兴为您提供帮助!起初它令人困惑,但很快就会成为第二天性。我很高兴您提到了授权:如果您要对用户进行认证(例如,通过设置 cookie),您还需要传递Access-Control-Allow-Credentials
标头。该行应如下所示:add_header Access-Control-Allow-Credentials "true";
。 (你说得对,通配符在这种情况下不起作用。)以上是关于AJAX CORS http 请求 nginx 拒绝的主要内容,如果未能解决你的问题,请参考以下文章
使用 ajax 发出 http 请求以获得基本授权和 cors
nginx ssl 拒绝不匹配的 server_name 请求