跨域问题
问题:什么是跨域?
跨域问题的来源是浏览器的安全机制,同源策略。
同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。
这是一个用于隔离潜在恶意文件的重要安全机制
也就是说,接口返回的数据被浏览器阻隔了。在用其他测试工具测试接口数据时,是可以看到数据返回的。
解决方案
- JSONP
- document.domain + iframe
- location.hash + iframe
- window.name + iframe
- postMessage
- Nginx 配置反向代理
- CORS(跨域资源共享)
1. JSONP 跨域方案
原理:通过利用 img、script、link 标签的 src
或 href
属性来实现。
( 在上述标签中,通常会请求一个同源的文件,但这些文件都没有被同源策略拦截 )
※ JSONP 跨域只能用于 get 方法
2. document.domain + iframe
document.domain 用于获取当前网页的域名
前提条件:两个域名必须属于同一个一级域名,所用到的协议、端口号都要一致
( 一级域名必须保持一致 )
常用需求:将当前页面下的图片上传到同源路径下的 img 文件夹
实现方法:
- 将页面 document.domain 的值设置为当前域名的一级域名
- 创建 iframe,并在 iframe 挂上 load 事件监听,进行上传图片
3. location.hash + iframe
location.hash 用于获取url地址栏中锚点(#)后的数据
通过iframe将需要传值的页面嵌套入当前页面,并给其附上hash值,传值页面需要根据其自身的hash值进行处理,并通过上述方法将新的hash值传回给原页面。
4. window.name + iframe
window.name 只要在一个window下,无论url怎么变化,只要设置好了
window.name
,之后都不会被改变。
即在iframe中,即使url在变化,iframe中的window.name也是一个固定的值。利用这点,即可实现跨域
5. postMessage
在HTML5中新增了
postMessage
方法,postMessage
可以实现跨文档消息传输。目前IE8、Firefox3、Opera9、Chrome3和Safari4都支持
postMessage
该方法能解决的跨域场景问题:
- 页面和其打开的新窗口的数据传递
- 多窗口之间消息传递
- 页面与嵌套的iframe消息传递
5.1 用法
postMessage(data, origin)
方法接收两个参数
-
data
HTML5规范支持任意基本类型或可复制的对象,但部分浏览器只支持字符串,所以传参时需用
JSON.stringify()
进行序列化 -
origin
协议 + 主机 + 端口号
也可以设置为
*
,表示可以传递给任意窗口,如果要指定和当前窗口同源的话设置为/
6. vue-cil 代理跨域
该方案适用于使用vue-cil脚手架搭建的框架
打开 config
文件夹下的 index.js
,并在 proxyTable
字段中加入以下代码
'/api': {
// 这里后台的地址模拟的;应该填写你们真实的后台接口
target: 'http://192.168.50.99:8080',
ws: false, // 是否使用了websocket
// 允许跨域
changOrigin: true,
pathRewrite: {
// 请求的时候使用这个api就可以
'^/api': ''
}
}
设置完成后,在axios封装文件(request.js)中将 baseUrl
设置为:
'/api'
即可完成跨域
如何在get方法中传入自定义头部数据
需要BE同事在代码中允许FE传输自定义头部字段。