1. 介绍
跨域:指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对 Javascript 施加的安全限制。
同源策略:是指协议,域名,端口都要相同,其中有一个不同都会产生跨域。具体场景如下所示:
跨域前端产生的报错如下所示,即从 http://localhost:8001
访问 http://localhost:88/api/sys/login
时被 CORS 策略阻止。
1 | Access to XMLHttpRequest at 'http://localhost:88/api/sys/login' from origin 'http://localhost:8001' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. |
2. 跨域流程
如下图是跨域的流程,具体关于非简单请求概念和其他跨域相关内容,可访问官网:跨源资源共享(CORS) - HTTP | MDN (mozilla.org)
3. 解决跨域方案
3.1 nginx 配置同源
根据产生跨域的原因,我们可以使用 nginx 对不同的请求配置成相同的地址和端口,然后在使用 nginx 内部进行请求转发,例如下图所示,这样可以有效解决跨域问题。
3.2 请求全局过滤
根据跨域流程我们知道浏览器首先会发送预检请求给服务器,然后根据服务器的响应是否允许实现跨域请求。因此我们只需要让服务器对指定的请求响应允许跨域请求即可,具体实现则是配置对应的响应头。常用的响应头如下所示:
- Access-Control-Allow-Origin:支持哪些来源的请求跨域
- Access-Control-Allow-Methods:支持哪些方法跨域
- Access-Control-Allow-Credentials:跨域请求默认不包含 cookie,设置为 true 可以包含 cookie
- Access-Control-Expose-Headers:跨域请求暴露的字段
- CORS请求时,XMLHttpRequest 对象的 getResponseHeader() 方法只能拿到6个基本字段: Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他字段,就必须在Access-Control-Expose-Headers里面指定。
- Access-Control-Max-Age:表明该响应的有效时间为多少秒。在有效时间内,浏览器无须为同一请求再次发起预检请求。请注意,浏览器自身维护了一个最大有效时间,如果该首部字段的值超过了最大有效时间,将不会生效。
下面以 SpringBoot 为示例,通过过滤器实现对请求进行跨域处理,具体代码如下:
1 | /** |