跨域相关原理及解决办法

1.什么是跨域?
从名字说是跨域名,其实不单单是跨域名,协议、域名、端口号三种都有影响。
跨域实际上是由浏览器的同源策略限制的。
2.什么浏览器同源策略
同源策略限制从一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的关键的安全机制。
浏览器同源策略最先有网景公司提出,之后所有支持JavaScript的浏览器都遵循这个策略。
浏览器同源策略,不阻止发出请求,只是请求的返回结果被浏览器阻止了,用户不能拿到请求的返回值。下面是例子:

// 页面地址 http://lkj.test.com
$.ajax({
    url: 'http://app.video.baidu.com/xda',
    data: {
        terminal:'pc',
		position:'fourChannelsSecIndexFilter',
		id:'fourChannelsSecIndexFilter',
		site:'http://v.hao123.com/dianshi_index/filter-true_area-%E5%86%85%E5%9C%B0_order-hot_pn-1_channel-tvplay',
		refer:''
    },
    dataType: 'json',
    timeout: 5000,
    success: function (ret) {
        console.log(ret);
    }
});

下面看结果:
h2
可以看到请求正常发出了,服务器收到了请求,但是由于跨域限制,浏览器阻塞了返回值,导致用户不能正常拿到返回值。
此请求服务器端设置了Access-Control-Allow-Origin,可以允许跨域,但是值是http://m.video.baidu.com,所以不能拿到返回值

3.浏览器同源策略限制哪些操作?
限制一个源里的文档或者脚本与另一个源的文档或者脚本的交互。
例子:

// 1.html
<script src="http://y0.ifengimg.com/base/jQuery/jquery-1.9.1.min.js"></script>
<img src="http://p1.ifengimg.com/a/2017_30/51497f0cd653666.jpg" height="360">
<iframe src="http://lkj.hao123.com:8220/"></iframe>
<script type="text/javascript">
	$.ajax({
        url: 'http://app.video.baidu.com/xda',
        data: {
            terminal:'pc',
			position:'fourChannelsSecIndexFilter',
			id:'fourChannelsSecIndexFilter',
			site:'http://v.hao123.com/dianshi_index/filter-true_area-%E5%86%85%E5%9C%B0_order-hot_pn-1_channel-tvplay',
			refer:''
        },
        dataType: 'json',
        timeout: 5000,
        success: function (ret) {
            console.log(ret);
        }
	});

</script>

结果:
图片和脚本正常外链加载。脚本报跨域错误
1.html是一个源,与来自于y0.ifengimg.com源的jquery-1.9.1.min.js资源、来自于p1.ifengimg.com源的51497f0cd653666.jpg、来自于app.video.baidu.com源的xda进行交互被浏览器的同源策略进行了限制。

同源策略控制了不同源之间的交互,例如在使用XMLHttpRequest 或 标签时则会受到同源策略的约束。交互通常分为三类:

a).通常允许进行跨域写操作(Cross-origin writes)。例如链接(links),重定向以及表单提交。特定少数的HTTP请求需要添加 preflight。
b).通常允许跨域资源嵌入(Cross-origin embedding)。之后下面会举例说明。
c).通常不允许跨域读操作(Cross-origin reads)。但常可以通过内嵌资源来巧妙的进行读取访问。例如可以读取嵌入图片的高度和宽度,调用内嵌脚本的方法,或availability of an embedded resource.
以下是可能嵌入跨源的资源的一些示例:

<script src="..."></script>标签嵌入跨域脚本。语法错误信息只能在同源脚本中捕捉到。
 <link rel="stylesheet" href="...">标签嵌入CSS。由于CSS的松散的语法规则,CSS的跨域需要一个设置正确的Content-Type消息头。不同浏览器有不同的限制: IE, Firefox, Chrome, Safari (跳至CVE-2010-0051)部分 和 Opera。
 <img>嵌入图片。支持的图片格式包括PNG,JPEG,GIF,BMP,SVG,...
 <video> 和 <audio>嵌入多媒体资源。
 <object>, <embed> 和 <applet>的插件。
@font-face引入的字体。一些浏览器允许跨域字体( cross-origin fonts),一些需要同源字体(same-origin fonts)。
 <frame> 和 <iframe>载入的任何资源。站点可以使用X-Frame-Options消息头来阻止这种形式的跨域交互。

总结:iframe、script、img、video、object、embed、link标签允许垮域引用资源
ajax、cookie、localstorage等被限制

4.绕过浏览器同源策略(hack)
4.1.jsonp
修改上面代码:

// 页面地址 http://lkj.test.com
$.ajax({
    url: 'http://app.video.baidu.com/xda',
    data: {
        terminal:'pc',
		position:'fourChannelsSecIndexFilter',
		id:'fourChannelsSecIndexFilter',
		site:'http://v.hao123.com/dianshi_index/filter-true_area-%E5%86%85%E5%9C%B0_order-hot_pn-1_channel-tvplay',
		refer:''
    },
    dataType: 'jsonp',
    timeout: 5000,
    success: function (ret) {
        console.log(ret);
    }
});

修改为jsonp方式
结果如下:
可以正常拿到请求返回值。
4.2.更改源
页面可能会更改其自己的来源,但有一些限制。脚本可以将 document.domain 的值设置为其当前域或其当前域的超级域。
4.3.CORS
其他方法见不同跨域方法的比较
5.总结

内嵌资源,如果没有进行外域的操作(比如a内嵌b,a不操作b,b也不操作a,即相互的js没有交互)则不会跨域,如果有进行外域的操作,则会跨域。

此条目发表在未分类分类目录。将固定链接加入收藏夹。

发表评论

电子邮件地址不会被公开。 必填项已用*标注