是谁引起的跨域?
跨域是浏览器(浏览器内核)的安全检测行为而并非是服务器端行为。
真正跨域作用的地方在于浏览器接收到服务器端响应的数据后,通过检查是否满足跨域的条件要求而决定是否对数据进行拦截丢弃的过程。
跨域的必要条件
- 浏览器限制: 即浏览器对跨域行为进行检测和阻止
-
触发跨域的三要素:
不同协议
、不同域名
、不同端口
,满足其一 - 发起的是xhr请求: 即发起的是XMLHttpRequest类型的请求
跨域的几种解决方案
- 开发阶段
- 解除浏览器安全限制(针对第一个必要条件)
- window
在chrome浏览器右键属性中的目标中添加--args --disable-web-security --user-data-dir
浏览器属性配置图
重新打开浏览器显示下图提示,表示成功
解除安全限制提示
- linux
直接运行命令行open -a "Google Chrome" --args --disable-web-security --user-data-dir
-
本地设置node代理服务器(针对第二个必要条件)
很多框架的cli都已经整合了本地代理服务器来进行跨域,配置也更加简单。 以vue-cli为例:
在config/index.js中简单配置即可
vue-cli跨域设置 原理:
在本地配置代理服务器 项目就直接请求本地服务器,这样就完美的避过了上面写的第二个必要条件。然后本地服务器再和远程服务器进行通信来获取数据。
跨域是浏览器的限制行为,服务器通信不存在跨域。
- 生产阶段
-
jsonp请求(针对第三个必要条件)
JSONP 方案原理就是通过动态创建script
标签,利用标签内src
属性发送同步请求。本质就是利用script
标签加载远程js的特性,理论上来说有src
属性的标签都可以。
通过浏览器控制台Network选项查看发现,JSONP发出去的请求类型是script
,img
标签src
属性发出去的请求类型是JSON
,他们都不是xhr
, 因为没有形成跨域的第三个条件,因此不会触发浏览器跨域检查策略。
虽然JSONP能处理跨域问题,但其实它存在很多弊端,主要如下:
- 需要服务器端修改代码支持: 服务器端不再返回json格式,而是返回固定格式的回调函数
- 只支持GET请求: 即使设置了请求类型为POST也无效,只支持GET
- 发送的不是XHR请求: 正因为这点才支持了跨域,然而也丢失了xhr强大的功能
-
服务器端配置
添加允许访问的域名白名单
// 允许跨域的域名,设置*表示允许除带Cookies信息的所有域名
res.addHeader("Access-Control-Allow-Origin", "http://localhost:8081");
这样在xhr请求的时候,浏览器判断请求源域名在允许访问的域名中,就不会进行请求数据的拦截。所以就不会存在跨域问题。
请求头 响应头
网友评论