前后端分离的项目使用nginx 解决 Invalid CORS request

server/2024/12/18 12:58:35/

我是这样打算的,前端用nginx代理,使用80 转443 端口走https
前端的地址就是http://yumbo.top 或https://yumbo.top

后端服务地址是:http://yumbo.top:8081

下面是我的完整配置,功能是正常的,加了注释

user  nginx;
worker_processes  1;error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;events {worker_connections  1024;
}http {include       /etc/nginx/mime.types;default_type  application/octet-stream;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;keepalive_timeout  65;#gzip  on;# include /etc/nginx/conf.d/*.conf;# 以下属性中以ssl开头的属性代表与证书配置有关,其他属性请根据自己的需要进行配置。server {listen 443 ssl;   #SSL协议访问端口号为443。此处如未添加ssl,可能会造成Nginx无法启动。server_name yumbo.top;  #将localhost修改为您证书绑定的域名,例如:www.example.com。root html;index index.html index.htm;ssl_certificate /etc/nginx/yumbo.top.pem;   #替换成您证书的文件名。ssl_certificate_key /etc/nginx/yumbo.top.key;   #替换成您证书的密钥文件名。ssl_session_timeout 5m;ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;  #使用此加密套件。ssl_protocols TLSv1 TLSv1.1 TLSv1.2;   #使用该协议进行配置。ssl_prefer_server_ciphers on;   charset utf-8;location / {root /etc/nginx/web;   #站点目录。index index.html index.htm;  }#/api是vue中配置的代理路径location /api/ {add_header Content-Type 'application/json; charset=utf-8';proxy_pass http://yumbo.top:8081/;#后端服务地址proxy_set_header Origin http://yumbo.top:8081/;#这个要和后端服务地址一样,不然会出现跨域问题proxy_set_header Host $proxy_host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;proxy_set_header Access-Control-Allow-Origin *;proxy_set_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS';proxy_set_header Access-Control-Allow-Headers 'Content-Type, Authorization';}}server {listen 80;server_name yumbo.top;rewrite ^(.*)$ https://${server_name}$1 permanent; }}

问题的发现

起初nginx没有配置好,出现了Invalid CORS request 或者403等之类的错误。
通过chrome无痕窗口访问网站,发现一个很奇特的现象,有个别几个接口是好的(login, menu, ringData)。
其他接口都出现了Invalid CORS request 状态403
我再三确认过axios 以及 后端springboot项目跨域都是允许的

axios我是这样配的,所有请求都是通过这个axios创建得到的axios对象,但是detail接口发现是403 response返回Invalid CORS request ,包括其他接口也都是403,就奇怪了,为什么那几个接口为什么没有出现跨域?

axios.create({baseURL: (process.env.NODE_ENV === 'production' ? process.env.server : '') + '/api',withCredentials: true,headers})

在这里插入图片描述

为了排查这个问题,我用postman去测接口。
比如去测这个detail接口https://yumbo.top/api/dashboard/ringData/detail
发现postman能成功返回数据,包括不走nginx代理,直接访问接口http://yumbo.top:8081/api/dashboard/ringData/detail
也都能正常返回数据
在这里插入图片描述

但是 !!! 部署上服务器后,就出现了上面截图 detail 跨域了。非常的困惑

后面看了这篇文章,了解了为什么会产生跨域:

  1. 403 Invalid CORS request 跨域问题 invalid+cors+request什么意思

一开始也没认真去看这篇文章,文章的内容和实际是有差别的。
有些场景可能多个因素造成跨域。

通过postman我确认了后端服务正常,nginx 80 转443 代理正常,接口能通过https://yumbo.top/api/dashboard/ringData/detail 获得数据,但是部署上去的项目就是会出现下面这种
在这里插入图片描述
因为看过之前提到的哪篇文章,我知道 跨域是根据http header中的Origin 和 Request URL进行比较。

一开始我没有怀疑是nginx的问题,因为我发现postman能够拿到接口数据,那按道理是前端axios与nginx之间的问题。

于是我尝试postman 的header中添加Origin

无非就是下面这些情况,一个一个试

  1. https://yumbo.top
  2. http://yumbo.top
  3. http://yumbo.top:8081

一开始呢,我将Origin 值和我nginx地址填的一致https://yumbo.top,我试了一下,我发现原先可以拿到接口数据的变成了和我chrome访问网站的结果一样Invalid CORS request
于是我又试了一下第3种情况 http://yumbo.top:8081 发现拿到了后端接口数据
在这里插入图片描述

于是我就回头找之前出现 Invalid CORS request 的请求头

发现Request Headers里有这个字段。于是就明白了,原来是axios自动的给请求头加了Origin,或者说是更底层 XMLRequest自动加的。
这个我们不用改axios,因为没必要改。
在这里插入图片描述
通过上述一系列的尝试,加上一些文章的内容,我们了解到,原来我遇到的跨域是因为我代理的后端服务地址http://yumbo.top:8081 而请求头中的Origin是https://yumbo.top(浏览器看到是是假的,因为后面被nginx转发了请求)

总结

得到Invalid CORS request的结果是因为Origin的值http://yumbo.top(前端浏览器,axios根据当前域自动添加的)和后端代理的接口地址http://yumbo.top:8081不一致。
我们知道nginx是可以修改请求头的,只要在nginx转发的那个地方加上Origin就可以解决这个问题。

下面是关键信息,只要这2个一致就行了

location /api/ {proxy_pass http://yumbo.top:8081/;#后端服务地址proxy_set_header Origin http://yumbo.top:8081/;#这个要和后端服务地址一样,不然会出现跨域问题
}

具体的其他一些关于nginx的配置,可以参考我前面完整的nginx配置


补充一下,为什么会出现个别请求没有出现跨域
因为后端springboot用的是@GetMapping
其他接口我都是用@PostMapping
根据我之前翻阅的文章知道,针对一些简单请求,比如get请求,或者个别请求是不会出现跨域的。
在这里插入图片描述


http://www.ppmy.cn/server/151178.html

相关文章

蓝桥杯数列求值(2019试题C)

【问题描述】 给定数列1,1,1,3,5,7,17……从第4项开始,每项都是前3项的和。求第20190324项的最后4位数字。 【答案提交】 这是一道结果填空题,考生只需要计算出结果并提交即可。本题的结果为一个4位整数(提示:答案的千位不为0)&a…

华为ensp--BGP路径选择-Preferred Value

学习新思想,争做新青年。今天学习的是BGP路径选择-Preferred Value 实验目的 理解BGP路由信息首选值(Preferred Value)的作用 掌握修改Preferred Value属性的方法 掌握通过修改Preferred Value属性来实现流量分担的方法 实验拓扑 实验要求…

高效数据集成:钉钉与企业系统无缝对接

钉钉数据集成案例分享:鸿巢基础资料-供应商账号(删除操作) 在企业信息化管理中,数据的准确性和及时性至关重要。本文将聚焦于一个具体的系统对接集成案例——钉钉数据集成到钉钉,详细探讨如何通过轻易云数据集成平台实现“鸿巢基础资料-供应…

Linux应用开发————mysql数据库

数据库概述 什么是数据库(database)? 数据库是一种数据管理的管理软件,它的作用是为了有效管理数据,形成一个尽可能无几余的数据集合,并能提供接口,方便用户使用。 数据库能用来干什么? 顾名思义,仓库就是用来保存东…

JS设计模式之访问者模式

前言 访问者模式(Visitor Pattern)是一种 行为设计模式,它允许在不改变对象结构的情况下,定义新的操作。 这种模式通过将操作封装在访问者对象中,使得可以在不修改被访问对象的情况下,增加新的功能。 本…

AI、大数据、机器学习、深度学习、神经网络之间的关系

AI、大数据、机器学习、深度学习、神经网络之间的关系 一、人工智能(AI)的概念 人工智能是指通过计算机程序或机器来模拟、实现人类智能的技术和方法。它旨在使计算机具备感知、理解、判断、推理、学习、识别、生成、交互等类人智能的能力,…

React简单了解

原理简化了解 import React from "react" import { createRoot } form "react-dom/client"const element React.createElement(p,{id: hello},Hello World! )const container document.querySelector(#root) const root createRoot(container) root.r…

2024年全球安全光幕系统行业总体规模、主要企业国内外市场占有率及排名

根据QYResearch研究团队调研统计,2023年全球安全光幕系统市场销售额达到了 亿元,预计2030年将达到 亿元,年复合增长率(CAGR)为 %(2024-2030)。中国市场在过去几年变化较快,2023年市场…