实战跨域

还是有一些漏网之鱼的

HTMLlink标签和CSSurl函数

link引入一个外部样式表。url指向一个资源,许多css属性都可以使用它,例如 @font-face list-style cursor等。 这是一个Material Design风格的按钮,这里通过link 引入material-components-web样式,@font-face引入Material Icons字体文件。


        
@font-face {
    font-family: 'Material Icons';
    font-style: normal;
    font-weight: 400;
    src: url(//fonts.gstatic.com/s/materialicons/v70/flUhRq6tzZclQEJ-Vdg-IuiaDsNc.woff2) format('woff2');
}

.material-icons {
    font-family: 'Material Icons';
    font-weight: normal;
    font-style: normal;
    font-size: 24px;
    line-height: 1;
    letter-spacing: normal;
    text-transform: none;
    display: inline-block;
    white-space: nowrap;
    word-wrap: normal;
    direction: ltr;
    -webkit-font-smoothing: antialiased;
}
        

        

HTMLscript标签

script 可以嵌入和引入外部可执行脚本,这里主要说的是引入跨域的JS。下面还是material-components-web的一个示例,只不过依赖JS:



        
var slider = new mdc.slider.MDCSlider(document.querySelector('.mdc-slider'));
        

HTMLimg标签

img标签可以嵌入图像。 百度一下这里使用了百度的图片。

百度一下
        

HTMLvideo audio标签


        

HTMLiframe标签

这种方式也是可以禁止的,MDN Web 文档就不可以。这里使用 iframe嵌入多吉搜索


        

cookie(有限制)

cookie 未遵循严格的同源策略,但是也是有限制的。//ddz.com/index.html 页面设置cookie时如果不指定domain ,iframe中 c1.ddz.com/cookie1.html 该页面不获取父页面的cookie

● 主域名是不给子域名设置cookie的。例如://ddz.com/index.html => document.cookie = "name=index.html;domain=c1.ddz.com";

● 主域名不设置domain,子域名是不能访问的。例如://ddz.com/index.html => document.cookie = "name=index.html;";之后 //c1.ddz.com/cookie1.html => document.cookie,这里不能获取主域名设置的cookie

● 主域名设置domain,子域名可以能访问。例如://ddz.com/index.html => document.cookie = "name=index.html;domain=ddz.com";之后 //c1.ddz.com/cookie1.html => document.cookie 这就就可以获取到了。如果你在浏览器F12中查看,你会发现主域名设置cookie会同时添加到子域名下

● 子域名设置domain,主域名可以能访问。例如://c1.ddz.com/cookie1.html => document.cookie = "age=18;domain=ddz.com";之后 //ddz.com/index.html => document.cookie 就可以取到

你不能做的一些事情

(1) Cookie、LocalStorage 和 IndexDB 无法读取。

(2) DOM 无法获得。

(3) AJAX 请求不能发送。

上面的问题可以解决吗?

先介绍一下测试环境。服务器用的是IIS,搭了一个站点,路径为"/p/web/problem/crossDomain";之后修改hosts文件,如下:

127.0.0.1 ddz.com
127.0.0.1 c1.ddz.com
127.0.0.1 c2.ddz.com
        

iframe搭配 document.domain

先说一下,主域名下的页面不能设置document.domain为子域名,否则会报错。例如: //ddz.com/index.html => document.domain = 'c1.ddz.com';

Uncaught DOMException: Failed to set the 'domain' property on 'Document': 'c1.ddz.com' is not a suffix of 'ddz.com'.

还有一点就是相应页面设置document.domain的时机,一定保证在跨域读取之前已经设置完成,否则还是会报跨域错误。

Uncaught DOMException: Blocked a frame with origin "http://c1.ddz.com" from accessing a cross-origin frame.

最后一点就是你可以在 //ddz.com/index.html 页面打印输出document.domain ,值为:"ddz.com"。但是如果你不显示设置他的值,照样是跨域错误。

documentDomain1.html:11 Uncaught DOMException: Blocked a frame with origin "http://c1.ddz.com" from accessing a cross-origin frame.

index.html:232 Uncaught DOMException: Blocked a frame with origin "http://ddz.com" from accessing a cross-origin frame.

iframe搭配 location.hash

在 //ddz.com/index.html 页面通过使用iframe并且设置路径时带上hash 值的方式给跨域页面传值,这并没有什么问题。问题是iframe 中的页面应答,该页面也可以通过上面的方式将相应传给与父页面同源的页面,例如:'//ddz.com/locationHash0.html#' + new Date().valueOf(); ,在 //ddz.com/locationHash0.html 这个页面就是通过window.parent.parent.location.hash设置 //ddz.com/index.html 页面的hash了。这可真够费劲的,子页面不能像parent.location.href = parent.location.href + "#" + new Date().valueOf();或者parent.location.hash = new Date().valueOf();这样 修改父页面的hash吗?答案是不可以的,虽然是主域和子域的关系,会报下面的错误。

locationHash1.html:17 Uncaught DOMException: Blocked a frame with origin "http://c1.ddz.com" from accessing a cross-origin frame.

此处的测试想要成功需要将上文中的document.domain = 'ddz.com';这句代码屏蔽掉。

iframe搭配 window.name

在 //ddz.com/index.html 页面通过使用iframe嵌入 //c1.ddz.com/windowName1.html 页面(该页面设置 window.name),onload之后再利用该iframe去加载和 //ddz.com/index.html 页面同源的页面://ddz.com/windowName0.html。这时读取iframe contentWindow.name 的值,这里获取到的就是第一次加载跨域页面设置的window.name。注意:第二次加载的同源页面不要设置 window.name,否则获取到的就是他的值了。

此处的测试想要成功需要将上文中的document.domain = 'ddz.com';这句代码屏蔽掉。

安全的跨源通信postMessage

JSONP

这里调用JSONP 教程 | 菜鸟教程获取数据

代理服务器、WebSocket、CORS等

这几种方式都和服务器端相关并且不太好测试,这里暂时就不写了……以后再说

参考链接

浏览器的同源策略 - Web 安全 | MDN

跨源资源共享(CORS) - HTTP | MDN

前端常见跨域解决方案(全)- SegmentFault

浏览器同源政策及其规避方法 - 阮一峰的网络日志

<url> - CSS(层叠样式表) | MDN

<script> - HTML(超文本标记语言) | MDN

HTML中的图片 - 学习 Web 开发 | MDN

<img>:图像嵌入元素 - HTML(超文本标记语言) | MDN