Nginx 解决跨域问题

问题由来

浏览器拒绝执行其它协议域名端口下的 ajax 运作:

我想自己做一个搜索网站,但我不会搜索技术,怎么办呢?如果能发起 ajax 请求到百度就好了呢,可以这样吗?
肯定不行,如果浏览器在自己的服务器域名对应的 html 页面内,发起 ajax 请求偷盗 www.baidu.com 域名下的内容来填充自己的页面,整个互联网秩序将混乱。

为了防止这种混乱,W3C 组织制定了浏览器安全规范,即 html 页面发起的 ajax 请求仅限于同协议域名端口后端范围,跨越域名的ajax请求不得执行,此谓跨域问题。

如下图:
在这里插入图片描述
在这里插入图片描述
而在日常工作中,我们自己有多个子系统,避免不了要有跨越子系统的 ajax 请求,此时,我们希望自己内部的各个子系统不必有这种跨域限制。

Jsonp 的解决之道

W3C 制定的规则不允许ajax跨域请求,却允许script标签发起跨域请求,如下:
在这里插入图片描述
因此,有人便扩展的 script 标签 src 源可以跨域的用法,来得到跨域名的请求信息。这便是 jsonp 的解决办法。
jsonp 的方法有其不美的地方,主要是两点:

  1. jsonp只能解决 GET 类的请求,其它类型的请求,script 标签无法做到
  2. 使用 jsonp 的方式,对应的后台程序必须对结果进行改造。将返回值做一个函数式包装。这对业务开发有较大侵入性,增加开发人员负担

CORS 的解决之道

Cross-Origin Resource Sharing (CORS),跨域资源共享。

W3C 制定跨域限制的本意,是防止页面领域安全混乱,即防止A公司不经B公司同意,使用 ajax 盗取B公司的服务内容。
出于这个本意,W3C改进了跨域的方案,即:如果B公司是同意将自己的内容分享给A公司的,跨域限制可放开,此方案即CORS方案,如下图:

在这里插入图片描述

nginx 配置跨域操作(CORS)

server {
        listen       80;
        server_name  test.enjoy.com;
        
	#是否允许请求带有验证信息
	add_header Access-Control-Allow-Credentials true;
	#允许跨域访问的域名,可以是一个域的列表,空格隔开,也可以是通配符*(不建议)
	add_header Access-Control-Allow-Origin  http://static.enjoy.com;
	#允许使用的请求方法,以逗号隔开,可以用 *
	add_header Access-Control-Allow-Methods 'POST,GET,OPTIONS,PUT,DELETE';
	#预检命令的缓存,如果不缓存每次会发送两次请求,单位为秒。
	#第一次是浏览器使用OPTIONS方法发起一个预检请求,第二次才是真正的异步请求
    add_header Access-Control-Max-Age 3600;
    
	#允许脚本访问的返回头
	add_header Access-Control-Allow-Headers 'x-requested-with,content-type,Cache-Control,Pragma,Date,x-timestamp';	
	#允许自定义的头部,以逗号隔开,大小写不敏感
	add_header Access-Control-Expose-Headers 'WWW-Authenticate,Server-Authorization';
	#P3P支持跨域cookie操作
	add_header P3P 'policyref="/w3c/p3p.xml", CP="NOI DSP PSAa OUR BUS IND ONL UNI COM NAV INT LOC"';
	
	if ($request_method = 'OPTIONS') {##OPTIONS类的请求,是跨域先验请求
            return 204;##http状态码 204 (无内容) 服务器成功处理了请求,但没有返回任何内容。可以返回 200 
        }
}

简单请求

对于比较简单的http请求(GET、POST、HEAD类型),无须浏览器来问,nginx服务器直接在响应头部,加入同意跨域的信号即可
在这里插入图片描述

复杂请求

对于复杂的http请求(PUT、DELETE、含json格式数据),浏览器会在发请求前,先发一道 OPTION 请求来询问。我们在Nginx上直接配置对此询问的回答即可
在这里插入图片描述
有了上述Nginx的两道配置,跨域问题自然而解,对业务毫无侵入性。在这里插入图片描述

CORS 对比反向代理

什么是反向代理:代理与反向代理
如何配置:proxy_pass 代理转发

对比两者,可以看到,两者适合的业务场景有不同:

反向代理

  • 将一台服务器作为网关和代理服务器,负责将请求转发到子系统(其它服务器)。
  • 用户的角度看,我只访问了一个域名,但其实可能你访问了很多服务器。
  • 是在访问其它服务器的服务器上配置(要转发到的服务器)。

跨域资源共享

  • 从 ajax 里拿其它服务器的资源。
  • 可以看到,这个主要是为了解决前端人员的问题。但 ajax 里其实就有一个 url 参数,所以反向代理也能解决这个问题。
  • 是在被访问的服务器上配置(允许访问其的服务器)。

所以综合二者业务场景的不同,我认为:

  1. 首先,确实进行了业务拆分,有业务在其他的服务器上,先配置 location,使用反向代理,这是必须的。做了这一步,你就已经解决了一部分跨域问题。
  2. 上面一步做完了以后,优先运用 CORS,毕竟这才是专业的跨域解决方案,并且是官方的。而且它配置比较简单,基本上配置一个允许访问的域名就行了,其它的都是不怎么变的。
nginx可以通过修改配置文件来解决跨域问题。在nginx的配置文件中,可以添加一些头信息来允许跨域请求。例如,可以使用add_header指令来设置Access-Control-Allow-Origin头信息,将其值设置为*表示允许所有的请求源进行跨域请求。同时,还可以使用add_header指令设置Access-Control-Allow-Methods头信息,指定允许的请求方法,如GET、POST、OPTIONS等。此外,还可以使用add_header指令设置Access-Control-Allow-Headers头信息,指定允许的请求头字段。\[1\]\[2\] 下面是一个示例的nginx配置文件片段: ``` location / { root /home/project/mini; index index.html index.htm; add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS'; add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization'; proxy_pass http://localhost:8080/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } ``` 在这个配置中,通过add_header指令设置了Access-Control-Allow-Origin、Access-Control-Allow-Methods和Access-Control-Allow-Headers头信息,以允许跨域请求。同时,使用proxy_pass指令将请求代理到本地的8080端口。\[1\] #### 引用[.reference_title] - *1* *2* [Nginx篇之解决跨域请求问题](https://blog.csdn.net/xu710263124/article/details/119916461)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [Nginx解决跨域问题](https://blog.csdn.net/weixin_55853065/article/details/127787284)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值