一、跨域的产生
跨域是因为浏览器的同源策略限制,是浏览器的一种安全机制。所谓同源是指两个页面具有相同的协议、主机和端口,任意不相同则产生跨域。
二、处理跨域的方式
1、jsonp
实现原理:页面之间限制发送ajax请求,但并未限制页面向其他页面请求js脚本,如img(或者script)标签可以引用其他页面之中的图片链接。
实现方式:当使用jsonp实现跨域时,需要前后端配合,一般情况下,ajax请求后返回的对象都是json对象,需要服务器端将json对象转换为callback函数的js脚本形式。也可以说,jsonp跨越就是通过动态添加script标签来调用返回的js文件。
实例:
//原生
<script>
var script = document.createElement('script');
script.type = 'text/javascript';
// 传入参数并执行对应的callback函数
script.src = 'http://www.xxx.xxx.xxx&callback=callback'
document.head.appendChild(script);
function callback(res) {
console.log(JSON.stringify(res))
}
</script>
//jquery
$.ajax({
url:'http://www.xxx.xxx.xx',
type:'get',
dataType:'jsonp',
jsonpCallback:'callback',
data:{}
})
//vue
this.$http.jsonp('http:xxx.xxxx.xxx', {
params: {},
jsonp: 'callback',
}).then((res) => {
console.log(res)
})
缺点:jsonp只支持get请求方式。
2、document.domain ——iframe跨域
实现原理:页面通过js强制设置document.domain为基础主域 实例:
//from页面中
<iframe src="下一级页面地址" frameborder="0" id="iframe"></iframe>
<script>
document.domain = 'aa.com'
var user = 'admin'
</script>
//to页面中
<script>
document.domain = 'aa.com'
console.log('获取上一级页面中的变量' + window.parent.user)
</script>
3、location.hash ——iframe跨域
实现原理:当两个页面之间需要跨域时,借助中间页面来实现,即相同域之间js直接访问,不同域之间借助iframe的location.hash传值
//1.html
<iframe src="1.html" frameborder="0" id="iframe" display="none"></iframe>
<script>
var iframe = document.getElementById('iframe');
//向2.html传hash
setTimeout(function () {
iframe.src = iframe.src + "#user=aaaa"
}, 1000)
//3.html的回调
function callback(res) {
console.log('3.html' + res)
}
</script>
// 2.html
<iframe src="3.html" frameborder="0" id="iframe" display="none"></iframe>
<script>
var iframe = document.getElementById('iframe');
//监听1.html传递的hash,传给3.html
window.onhashchange = function () {
iframe.src = iframe.src + location.hash
}
</script>
//3.html
<script>
//监听2.html传递的hash
window.onhashchange = function () {
window.parent.parent.callback('didi' + location.hash.replace('#user=', ''))
}
</script>
3、postMessage
window.postMessage() 方法允许来自一个文档的脚本可以传递文本消息到另一个文档里的脚本,而不用管是否跨域。
postMessage 可用于解决以下方面的问题:
- 页面和其打开的新窗口的数据传递
- 页面与嵌套的 iframe 消息传递
- 多窗口之间消息传递
实例:
//1.html
<iframe id="iframe" src="http://localhost:8080/2.html" style="display:none;"></iframe>
<script>
var iframe = document.getElementById('iframe');
iframe.onload = function() {
var data = { name: 'lch'};
iframe.contentWindow.postMessage(JSON.stringify(data), 'http://localhost:8080');
};
window.addEventListener('message', function(e) {
conosle.log('2.html——' + e.data);
}, false);
</script>
//2.html
<script>
window.addEventListener('message', function(e) {
console.log('1.html——' + e.data);
var data = JSON.parse(e.data);
if (data) {
data.number = 16;
window.parent.postMessage(JSON.stringify(data), 'http://localhost:8080');
}
}, false);
</script>
4、vue跨域
在webpack.config.js中配置
module.exports = {
entry: {},
module: {},
...
devServer: {
historyApiFallback: true,
proxy: [{
context: '/login',
target: 'http://www.xxxx.com:8080', // 代理跨域目标接口
changeOrigin: true,
secure: false, // 当代理某些https服务报错时用
cookieDomainRewrite: 'www.xxxx.com' // 可以为false,表示不修改
}],
noInfo: true
}
}