跨域(补充)

document.domain

Cookie是服务器写入浏览器的信息,只有同源的页面才能共享。但是,如果两个页面的一级域名一样,二级域名不一样,则允许通过将两个页面的document.domain共享资源。

域名的级别

  • 顶级域名/一级域名:比如:.com .cn .org,之后的N级域名就是在前面的(N-1)级域名前追加一级。
  • 二级域名:就是在顶级域名/一级域名前面追加一级,比如:ertsul.cn 或者 baidu.com

document.domain + Cookie

举例说明,非同源的两个页面A和B,A的地址为[http://a.example.com/a.html,B的地址为:http://b.example.com/b.html。这时,只要设强制置 A 和 B 的 document.domain 相同,就可以实现跨域请求了。

// A
document.domain = 'example.com'
document.cookie = 'Hello, I save a cookie.'
// B
document.domain = 'example.com'
document.cookie = 'Hello, I save a cookie.'

上面的例子,通过将AB两个页面设置相同的document.cookie,然后在A页面设置一个cookie,在B页面就可以获取A页面的cookie。

document.domain + iframe

这种方法的实现原理跟document.domain+Cookie是一样的,都是将两个不同的页面设置相同的document.domain,不同的是不需要通过设置cookie获取数据,而是通过父子两个窗口进行通信。

举个例子,A和B页面非同源,A页面内嵌一个iframe,加载这B页面。A的地址为:http://a.example.com/a.html,B的地址为:http://b.example.com/b.html

// A
<iframe id="iframe" src="http://b.example.com/b.html"></iframe>
<script>
 document.domain = 'example.com';
 var hi = 'hello';
</script>

// B
<script>
 document.domain = 'example.com';
 // 获取父窗口中变量
 alert(window.parent.hi);
</script>

location.hash + iframe

什么是location.hash?也就是片段标识符(fragment identifier)?指的是在URL的后面添加#号,这个符号后面的值就是location.hash。这样呢,就可以在不同源的两个页面(iframe父子页面)的后面添加hash值,进行监听。

举例:AB两个页面非同源,A页面内嵌了一个非同源地址的B页面。【 A将数据通过hash传递给B 】

// A页面
<iframe src="A的地址"></iframe>
<input type="text" name="" value="">
<button type="button">btnbtn</button>
<script>
 window.onload = function () { 
 document.getElementsByTagName('button')[0].addEventListener('click', function () { 
 let data = document.getElementsByTagName('input')[0].value
 document.getElementsByTagName('iframe')[0].setAttribute('src', 'A的地址#' + data)
 })
 }
</script>

// B页面
<script>
 window.onhashchange = function () { 
 console.log(window.location.hash);
 }
</script>

分析:A通过hash将数据传递给B,B页面通过window.onhashchange进行监听,通过window.location.hash获取数据。

window.name

浏览器窗口有window.name属性。这个属性的最大特点是,无论是否同源,只要在同一个窗口里,前一个网页设置了这个属性,后一个网页可以读取它。name值在不同的页面(甚至不同域名)加载后依旧存在,并且可以支持非常长的name值(2MB)。
实现思路:A和B为非同源的页面。在A中打开一个新窗口B,在B中将信息写入window.name属性,然后,B跳转到与A同源的另一个页面C(AC同源,C页面可以说是代理页面,可以设置为空白页),这样A窗口就可以获取B窗口的window.name属性值了。

// 在A打开子窗口B,并在B中写入window属性
window.name = data
// B跳转到C(AC同源)
location = '...'
// A读取B的window.name
let data = document.getElementById('myFrame').contentWindow.name

postMessage实现跨域

postMessage是html5提供的API,即:跨文档通信API(Cross-document messaging),是为数不多的可以跨域操作的window属性之一。这个API为window对象新增加了一个window.postMessage方法,允许跨窗口通信,无论这些窗口是否同源。
这个API可以解决这些问题:

  • 页面和其打开的新窗口的数据传递。
  • 多窗口之间消息传递。
  • 页面与嵌套的iframe消息传递。
  • 上面三个场景的跨域数据传递。

postMessage(data, origin)

这个方法会接受两个参数,这两个参数分别是:

  • data:html5规范支持任意基本类型或可复制的对象,但部分浏览器只支持字符串,所以传参时最好用JSON.stringify()序列化。
  • origin:协议+主机+端口号,也可以设置为”*”,表示可以传递给任意窗口,如果要指定和当前窗口同源的话设置为”/“。

举一个例子:

// A页面
let newPage = window.open('http://b.example.com', 'title')
newPage.postMessage('hello, I am a page.', 'http://b.example.com')
// B页面监听
window.addEventListener('message', function (e) {
 e.data
}, false)
// B向A发送消息(子窗口想父窗口发送消息)
window.opener.postMessage('Nice to see you', 'http://a.example.com');

这样子,也可以实现跨域的访问。当然,子窗口也可以发送消息给父窗口,父子窗口的监听方法一样。

message事件对象主要有三个属性:

  • event.source:发送消息的窗口。
  • event.origin:发送消息的网址。
  • event.data:发送的数据。

CORS

CORS是跨域资源分享(Cross-Origin Resource Sharing)的缩写。跟JSONP相比较,JSONP只能实现GET方法的请求,而CORS则允许任何类型的请求。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,496评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,407评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,632评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,180评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,198评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,165评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,052评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,910评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,324评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,542评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,711评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,424评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,017评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,668评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,823评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,722评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,611评论 2 353