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-Typeapplication/json,而且您没有使用非简单的标头,您还必须为Content-Type 标头提供特定权限,Accept-EncodingDNT 也是如此

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 之间的错误请求错误

Spring-Boot之Admin服务监控-9

如何集成 AngularJS 和 Spring-OAuth2?

在 spring boot+security+angularjs 中使用 angular-routing(ui-sref) 刷新页面

spring-boot系列:初试spring-boot