Nginx解决跨域(CORS)问题
本文最后更新于:2023-03-13, 23:48:50
0、问题出现
事情是这样的,我在Nginx里配置了两个服务,一个监听5000端口,用来代理前端,一个监听7000端口,用来代理后端。

然而在前端调用后端接口时,浏览器报跨域错误

再看一下控制台:

1、什么是跨域
跨域是指a页面想获取b页面资源,如果a、b页面的协议、域名、端口、子域名不同,或是a页面为ip地址,b页面为域名地址,所进行的访问行动都是跨域的,而浏览器为了安全问题一般都限制了跨域访问,也就是不允许跨域请求资源。
跨域问题的根本原因:因为浏览器受到同源策略的限制,当前域名的js只能读取同域下的窗口属性。什么叫做同源策略?就是不同的域名, 不同端口, 不同的协议不允许共享资源的,保障浏览器安全。同源策略是针对浏览器设置的门槛。
只有访问类型为XHR(XMLHttpRequest)的才会出现跨域。XHR是基于XML的HTTP请求,XHR用于在后台与服务器交换数据。XHR是一个浏览器接口,使得Javascript可以进行HTTP(S)通信,ajax就是基于浏览器提供的XHR对象来实现的。ajax,可以实现异步的加载网页也就是说可以在不重新加载整个网页的情况下,对网页的某部分进行更新。浏览器端发送的请求只有XHR 或 fetch 发出的才是 ajax 请求, 其它所有的都是非 ajax 请求,ajax 请求是一种特别的 http 请求。当浏览器端接收到ajax 请求,浏览器不会对界面进行任何更新操作, 只是调用监视的回调函数并传入响应相关数据。
2、解决方案
在nginx中添加跨域配置,可以添加在server字段,应用于整个server,也可以添加在server:location字段下,应用于单个location。nginx配置文件通过使用add_header指令来设置响应头response header。当前层级无 add_header 指令时,则继承上一层级的add_header。相反的若当前层级有了add_header,就无法继承上一层的add_header。
1 | |
根据上述方案,我在后端服务加上如下配置:

修改完后,nginx重新加载配置,问题就解决啦
1 | |
当然,如果你的后端不用Nginx代理,前端直接访问后端的话,还可以用这种方法:
Springboot项目,添加一个配置类
1 | |
其他语言的思路也差不多,就是在响应返回给浏览器之前,在response header里加上那几个参数就好了。
浏览器看到服务器返回的响应头里面有这几个参数,就不会报跨域的异常了

3、其他问题
(1)加了上面的Nginx配置还有跨域问题,http状态码是4XX或5XX。
经百度发现,Nginx add_header 只对2XX,3XX 这些状态码生效,对于4XX,5XX这些状态码是不生效的。
解决办法:添加: always
1 | |
这两个配置后面加上always就解决了。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!