为什么调用 API 时会出现 CORS 错误?
Why CORS error come out when I call an API?
我部署了一个项目,它有两个 API,分别是 login
和 loadMenu
,到服务器。当我调用 login
API 时,一切正常,我得到了结果。
但是当我尝试调用 loadMenu
API 时,出现了 CORS 问题。
这是我的 nginx 配置文件:
server {
listen 80;
# set proper server name after domain set
server_name xxxxxx;
# Add Headers for odoo proxy mode
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
proxy_set_header X-Client-IP $remote_addr;
proxy_set_header HTTP_X_FORWARDED_HOST $remote_addr;
# odoo log files
access_log /var/log/nginx/odoo15-access.log;
error_log /var/log/nginx/odoo15-error.log;
# increase proxy buffer size
proxy_buffers 16 64k;
proxy_buffer_size 128k;
proxy_read_timeout 900s;
proxy_connect_timeout 900s;
proxy_send_timeout 900s;
# force timeouts if the backend dies
proxy_next_upstream error timeout invalid_header http_500 http_502
http_503;
types {
text/less less;
text/scss scss;
}
# enable data compression
gzip on;
gzip_min_length 1100;
gzip_buffers 4 32k;
gzip_types text/css text/less text/plain text/xml application/xml application/json
application/javascript application/pdf image/jpeg image/png;
gzip_vary on;
client_header_buffer_size 4k;
large_client_header_buffers 4 64k;
client_max_body_size 0;
add_header 'Access-Control-Allow-Origin' "$http_origin" always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
location / {
#add_header 'Access-Control-Allow-Origin' "$http_origin" always;
#add_header 'Access-Control-Allow-Credentials' 'true' always;
if ($request_method = OPTIONS) {
add_header 'Access-Control-Allow-Origin' "$http_origin"; # DO NOT remove THIS LINES (doubled with outside 'if' above)
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Max-Age' 1728000; # cache preflight value for 20 days
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'My-First-Header,My-Second-Header,Authorization,Content-Type,Accept,Origin';
add_header 'Content-Length' 0;
add_header 'Content-Type' 'text/plain charset=UTF-8';
return 204;
}
if ($request_method = POST) {
add_header 'Access-Control-Allow-Origin' "$http_origin";
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' *;
}
#proxy_set_header host $http_host;
proxy_pass http://127.0.0.1:8069;
# by default, do not forward anything
proxy_redirect off;
proxy_cookie_path / "/; secure; HttpOnly;SameSite=None";
}
location /longpolling {
proxy_pass http://127.0.0.1:8072;
}
location ~* .(js|css|png|jpg|jpeg|gif|ico)$ {
expires 2d;
proxy_pass http://127.0.0.1:8069;
add_header Cache-Control "public, no-transform";
}
# cache some static data in memory for 60mins.
location ~ /[a-zA-Z0-9_-]*/static/ {
proxy_cache_valid 200 302 60m;
proxy_cache_valid 404 1m;
proxy_buffering on;
expires 864000;
proxy_pass http://127.0.0.1:8069;
}
}
这里是错误信息
Access to fetch at 'http://127.0.0.1:8069/web/login?redirect=http%3A%2F%2F127.0.0.1%3A8069%2Fweb%2Fwebclient%2Fload_menus%2F1652856182783' (redirected from 'http://IP/web/webclient/load_menus/1652856182783') from origin 'http://localhost:8069' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
在此处使用 stab-in-the-dark,但我猜您在 127.0.0.1:8069
(在服务器上)的 API 正在响应 fully-qualified 重定向 URL , 例如
< HTTP/1.1 302 Found
< Location: http://127.0.0.1:8069/web/login?...
这显然不是 URL 服务器内部网络之外的任何东西都可以访问的。
您缺少的是 proxy_redirect 配置以重写 Location
响应 headers 以使用 外部 地址...
proxy_redirect default;
# or the more verbose equivalent
# proxy_redirect http://127.0.0.1:8069 /;
如您的 last attempt at this question, it's usually a sign of something wrong with your API design 所述,如果它以 301 / 302 重定向响应。
我部署了一个项目,它有两个 API,分别是 login
和 loadMenu
,到服务器。当我调用 login
API 时,一切正常,我得到了结果。
但是当我尝试调用 loadMenu
API 时,出现了 CORS 问题。
这是我的 nginx 配置文件:
server {
listen 80;
# set proper server name after domain set
server_name xxxxxx;
# Add Headers for odoo proxy mode
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
proxy_set_header X-Client-IP $remote_addr;
proxy_set_header HTTP_X_FORWARDED_HOST $remote_addr;
# odoo log files
access_log /var/log/nginx/odoo15-access.log;
error_log /var/log/nginx/odoo15-error.log;
# increase proxy buffer size
proxy_buffers 16 64k;
proxy_buffer_size 128k;
proxy_read_timeout 900s;
proxy_connect_timeout 900s;
proxy_send_timeout 900s;
# force timeouts if the backend dies
proxy_next_upstream error timeout invalid_header http_500 http_502
http_503;
types {
text/less less;
text/scss scss;
}
# enable data compression
gzip on;
gzip_min_length 1100;
gzip_buffers 4 32k;
gzip_types text/css text/less text/plain text/xml application/xml application/json
application/javascript application/pdf image/jpeg image/png;
gzip_vary on;
client_header_buffer_size 4k;
large_client_header_buffers 4 64k;
client_max_body_size 0;
add_header 'Access-Control-Allow-Origin' "$http_origin" always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
location / {
#add_header 'Access-Control-Allow-Origin' "$http_origin" always;
#add_header 'Access-Control-Allow-Credentials' 'true' always;
if ($request_method = OPTIONS) {
add_header 'Access-Control-Allow-Origin' "$http_origin"; # DO NOT remove THIS LINES (doubled with outside 'if' above)
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Max-Age' 1728000; # cache preflight value for 20 days
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'My-First-Header,My-Second-Header,Authorization,Content-Type,Accept,Origin';
add_header 'Content-Length' 0;
add_header 'Content-Type' 'text/plain charset=UTF-8';
return 204;
}
if ($request_method = POST) {
add_header 'Access-Control-Allow-Origin' "$http_origin";
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' *;
}
#proxy_set_header host $http_host;
proxy_pass http://127.0.0.1:8069;
# by default, do not forward anything
proxy_redirect off;
proxy_cookie_path / "/; secure; HttpOnly;SameSite=None";
}
location /longpolling {
proxy_pass http://127.0.0.1:8072;
}
location ~* .(js|css|png|jpg|jpeg|gif|ico)$ {
expires 2d;
proxy_pass http://127.0.0.1:8069;
add_header Cache-Control "public, no-transform";
}
# cache some static data in memory for 60mins.
location ~ /[a-zA-Z0-9_-]*/static/ {
proxy_cache_valid 200 302 60m;
proxy_cache_valid 404 1m;
proxy_buffering on;
expires 864000;
proxy_pass http://127.0.0.1:8069;
}
}
这里是错误信息
Access to fetch at 'http://127.0.0.1:8069/web/login?redirect=http%3A%2F%2F127.0.0.1%3A8069%2Fweb%2Fwebclient%2Fload_menus%2F1652856182783' (redirected from 'http://IP/web/webclient/load_menus/1652856182783') from origin 'http://localhost:8069' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
在此处使用 stab-in-the-dark,但我猜您在 127.0.0.1:8069
(在服务器上)的 API 正在响应 fully-qualified 重定向 URL , 例如
< HTTP/1.1 302 Found
< Location: http://127.0.0.1:8069/web/login?...
这显然不是 URL 服务器内部网络之外的任何东西都可以访问的。
您缺少的是 proxy_redirect 配置以重写 Location
响应 headers 以使用 外部 地址...
proxy_redirect default;
# or the more verbose equivalent
# proxy_redirect http://127.0.0.1:8069 /;
如您的 last attempt at this question, it's usually a sign of something wrong with your API design 所述,如果它以 301 / 302 重定向响应。