跨域问题

冰岩作坊 November 17, 2022

跨域原因

解决方法

前端代理
##### 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 的值为“*”