跨域

10 篇文章 0 订阅
6 篇文章 0 订阅

不同域之间相互请求资源,就算作跨域,产生跨域的主要原因是因为同源策略。同源策略要求源相同才能正常进行通信,也就是协议、域名、端口都完全一致。但是请求跨域了,我们的请求也同样发了出去,只是浏览器拦截了响应,同时也说明跨域并不能完全阻止CSRF,因为请求发出去了。

如何跨域

常用的跨域方法有JSONPCORS, postmessage

1. JSONP
原理:通过<script>标签引入一个js文件,这个js文件被引入成功后执行我们在url参数中指定的函数,并且用参数的方式传入我们需要的json数据,jsonp需要服务器配合

原生

<script>
	function getData (item) {
		return item;
	}
</script>
<script
	type="text/javascript"
	src="url"></script>

ajax

$.ajax({
	url: "url",
	type: "get",
	dataType: "jsonp", // 请求方式
	jsonpCallback: "handleCallback", // 回调函数
	data: {}
})

vue

this.$https.jsonp("url", {
	params: {},
	jsonp: "handleCallback"
}).then((res) => {});

使用JSONP方式进行跨域,兼容性比较好,但是也存在缺点,比如:

  • 支持GET请求,不支持POST请求
  • 不能解决不同于的两个页面或iframe之间进行数据通信
  • JSONP如果从带有恶意代码的不安全域中加载代码执行,会存在安全隐患

2. CORS
一整个CORS通信过程,都是浏览器自动完成,不需要用户的参与,和AJAX通信没有差别,所以,实现CORS通信的关键是服务器,只要后端实现了CORS接口,就可以实现跨域。服务端设置Access-Control-Allow-Origin就可以开启CORS,这个属性是用来设置哪些域名可以访问,如果设置了通配符,就代表所有域名都可以访问。

使用node中间件express示例

app.use((req, res, next) => {
	// 允许跨域访问的域名
	res.header("Access-Control-Allow-Origin", "*");
	res.header("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE, OPTIONS");
	res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization, Access-Control-Allow-Credentials");
})

这个请求会验证Authorization字段,我们只需要在回调中过滤掉options方法即可。
虽然CORS使用简单而且安全,也支持POST方式,但是CORS还属于一种新型的跨域问题解决方案,存在兼容问题,目前只支持IE10以上。

3. document.domain

document.domain这种方式只能用于二级域名相同的情况下,通过js设置document.domain为主域就实现了同域

// 父窗口 // a.html
<iframe id="iframe" src="url/b.html"></iframe>
<script>
	document.domain = "domain.html";
	var str = "123";
</script>
// 子窗口  b.html
<script>
	document.domain = "domain.html";
	// 获取父窗口变量
	console.log(window.parent.str);
</script>

4. postMessage
window.postMessage(message, origin);接受两个参数,第一个参数message是要发送的信息,只能是字符串格式,第二个参数origin限定域,也可以设置为通配符*

// 发送消息
window.parent.postMessage('message', 'url')
// 接收消息
window.addEventListener('message', event => {
	var origin = event.origin || event.originalEvent.origin;
    if (origin === 'url') {
    	console.log('ok');
    }
})

5. window.name
window的生命周期内,所有的页面都共有一个window.name,并且一直存在,不会因有新的页面被重置,每个页面对window.name都有读写的权限。

  1. Vue解决跨域的方式
    配置proxy代理
module.exports = {
  proxy: {
        '/api': {
            target: 'url',  // 接口域名
            secure: false,  // 如果是https接口,需要配置这个参数
            changeOrigin: true,  //是否跨域
            pathRewrite: {
                '^/api': '' //路径重写
            }              
        }
  }
}

将这个文件引入到config下的index.js中将proxyTable插入到dev对象中进行跨域使用

7. 后台跨域
一般有两种解决办法
1. 将后台返回的数据格式改为jsonp
2. 后台中添加header,将域名访问设为通配符*,或者指定某个具体域名

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值