跨域原因
- 浏览器(所以在APP,小程序上不会有这些问题)重要的安全策略—同源策略
- 源=协议(https/http)+主机+端口,只有两个地址的源相同则称之为同源,否则就会产生跨域
- 那么当页面的源和页面运行过程中加载的源不一致时,出于安全考虑就会对跨域资源访问进行限制.其中如果是Ajax请求,同源政策就会直接禁止它访问静态资源
解决方法
前端代理
- 有时候生产环境没问题,开发环境存在跨域,跨域配置前端代理解决问题
- 那么通过代理方式将请求转发到服务器,避免了跨域访问
引用自掘金```
//vite配置例子 server: , // 正则表达式写法 ‘^/fallback/.*’: }
##### JSONP 神奇的方法
* 在浏览器中script元素标签的src属性并不被同源策略所约束
* 那么在服务器拿到请求后响应一段代码,这段代码是一个函数调用,调用客户端预先生成的函数,并把所需数据作为参数传入函数,从而实现了数据的传递
//页面A中<script type="text/javascript">//回调函数function callback(data) script><script type="text/javascript" src="http://localhost:20002/test.js">script>//text.js中callback()
* 缺点非常明显,首先这种方法是非官方的一种传输方式,其次只能支持GET请求
### CORS
* CORS是基于http1.1的一种跨域解决方案,它的全称是Cross-Origin Resource Sharing,跨域资源共享。
* 它的总体思路是:如果浏览器要跨域访问服务器的资源,需要获得服务器的允许
#### CORS规定三种不同的交互模式
##### 简单请求
###### 特点
* 方法为get post head
* 请求头只包含安全的字段,如Accept Accept-Language,而像Authorization这种就不行
* 请求头中的Content-Type只包含text/plain multipart/form-data applicaiton/x-www-form-urlencoded
###### 交互规范
* 请求头会添加Origin字段,会告诉服务器哪个源地址在跨域请求
* 响应头会添加Access-Control-Allow-Origin
* 可以是*表示允许所有源访问
* 也可以是具体的源
##### 需要预检的请求
* 如果不是上面的简单请求,那么浏览器会按照下面流程处理
###### 交互规范
* 浏览器发送预检请求,询问服务器是否允许
* 服务器允许
* 浏览器发送真实请求
* 服务器完成真实的响应
* 比如我在请求头中添加了Authorization用来携带token那么这时候浏览器就会认为这不是一个简单请求
* 首先会发出一个options预检请求
* Origin:请求的源,和简单请求的含义一致
* Access-Control-Request-Method:后续的真实请求将使用的请求方法
* Access-Control-Request-Headers:后续的真实请求会改动的请求头
* 它不包含请求体,只包含了请求后续要做的事情
* 请求头中包含
* 服务器会进行响应
* Access-Control-Allow-Origin:和简单请求一样,表示允许的源
Access-Control-Allow-Methods:表示允许的后续真实的请求方法
Access-Control-Allow-Headers:表示允许改动的请求头
Access-Control-Max-Age:告诉浏览器,多少秒内,对于同样的请求源、方法、头,都不需要再发送预检请求了
* 浏览器发送真实请求
##### 附带身份凭证的请求
* 一般情况下ajax跨域请求不会附带cookie,这时需要进行设置:
* const xhr=new XMLHttpRequest();xhr.withCredentials=true;
* 这时这个请求就变成一个附带身份凭证的请求了,这时候它的请求头中就会添加cookie字段
* 这时候需要在响应头中添加Access-Control-Allow-Credentials:true
* 对于附带身份凭证的请求,服务器不得设置 Access-Control-Allow-Origin 的值为“*”