Angularjs + Spring-boot + nginx的CORS问题
Posted
技术标签:
【中文标题】Angularjs + Spring-boot + nginx的CORS问题【英文标题】:CORS problem with Angularjs + Spring-boot + nginx 【发布时间】:2019-05-17 02:32:20 【问题描述】:所以我这几天一直在拔头发。我有一个后端服务器,使用带有 Rest API 的 Spring-boot
这个服务器是使用 AngularJS 从前端接口调用的,也由 nginx 处理。
一切都在本地运行。每当我尝试从前端向后端发出请求时,都会收到以下错误:
我知道你的想法:简单,只需添加 add_header 'Access-Control-Allow-Origin' 'http://[MY_IP]';到后端的 nginx.conf 文件,一切都会正常工作,比如here。或here。
但事实并非如此。我尝试了一切,将其移动到不同的位置,放置“*”而不是地址,启用和禁用 SSL……唯一有效的是当我在浏览器中手动禁用跨域限制时。最好的部分是,当我禁用这些限制时,我可以在浏览器的调试控制台中看到 Access-Control-Allow-Origin 标头设置为 http://[MY_IP]!
知道可能出了什么问题吗?
这是我的nginx.conf
文件:
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events
worker_connections 1024;
http
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
这是我的/etc/nginx/sites-enabled/default.conf
文件:
upstream backend_api
server 10.34.18.2:8080;
server
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /var/www/html/;
index index.html;
client_max_body_size 5M;
location /todos
access_log /var/log/nginx/todos.backend.access.log;
error_log /var/log/nginx/todos.backend.error.log;
proxy_set_header HOST $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://backend_api;
location /
access_log /var/log/nginx/todos.frontend.access.log;
error_log /var/log/nginx/todos.frontend.error.log;
try_files $uri $uri/ =404;
我创建了一个符号链接:
ln -s /etc/nginx/sites-available/default /etc/nginx/sites-enabled/
【问题讨论】:
您是否尝试将请求代码中的 URL 更改为http://10.34.18.2:8080/docs/
(带有斜杠)?问题是,i.stack.imgur.com/eFKpE.png 屏幕截图没有显示任何错误——相反,该屏幕截图仅显示成功向http://10.34.18.2:8080/docs
发出请求,并且服务器响应(非错误)302 重定向到http://10.34.18.2:8080/docs/
。所以服务器基本上只是说,“你忘记在请求 URL 中添加尾部斜杠。”。如果在 devtools 控制台中记录了其他错误,请将其添加到问题中。
如果您的代码向其发出请求的 API 端点是 Spring Boot 服务器,您会意识到该服务器必须发回 Access-Control-Allow-Origin,对吧?因此,如果您遇到的真正问题是浏览器在 devtools 控制台中记录了“缺少 Access-Control-Allow-Origin 标头”消息,则解决方法是配置 Spring Boot 服务器以发回该标头。如果您的请求不会发送到 nginx 服务器,那么您的 nginx 配置是无关紧要的(无论如何,问题中的 nginx 配置 sn-ps 不会显示在任何地方设置的 Access-Control-Allow-Origin 标头......)
【参考方案1】:
我不确定这是否会使cors
工作,但它可能有助于接近解决方案:
Access-Control-Allow-Origin: http://[MY_IP]
不是您需要处理的唯一标头。
由于Content-Type
是application/json
,而且您没有使用非简单的标头,您还必须为Content-Type
标头提供特定权限,Accept-Encoding
和DNT
也是如此
Access-Control-Allow-Headers: Content-Type, Accept-Encoding, DNT
我不确定这个特定的GET
,但无论如何也是允许的方法:
Access-Control-Allow-Methods: GET
如果您要发送 cookie、授权标头或客户端证书进行身份验证:
Access-Control-Allow-Credentials: true
我不认为这是您当前的情况,但请注意,返回 Access-Control-Allow-Credentials: true
并在 Access-Control-Allow-Origin
响应中盲目复制收到的 Origin
,可使任何站点冒充凭据所有者访问您的服务器.
并且以防万一,ACAO: *
和 ACAC: true
将无法按照规范工作。
您可能还需要注意在 cors 预检期间调用的 OPTIONS
方法,该方法应与实际调用将响应的内容保持一致。
请记住,不返回这些标头之一就是拒绝它的方法。
参考:CORS - MDN
【讨论】:
以上是关于Angularjs + Spring-boot + nginx的CORS问题的主要内容,如果未能解决你的问题,请参考以下文章
带有 spring-boot 和 angularjs 的 CORS 不起作用
通过发布请求,spring boot 和 angularjs 之间的错误请求错误
如何集成 AngularJS 和 Spring-OAuth2?
在 spring boot+security+angularjs 中使用 angular-routing(ui-sref) 刷新页面