Skip to content

跨域那点事 #25

@hoperyy

Description

@hoperyy

这里就不介绍跨域是什么了,重点:协议、域名、端口

下面是如何处理跨域问题的方法:

CORS

详见 阮一峰的 跨域资源共享 CORS 详解

jsonp

原理:客户端动态构造 script 标签,src 指向跨域资源,服务器返回 回调函数包裹参数 的形式触发客户端回调函数执行。

document.domain

  • 使用条件

    两个页面(A、B)之间通信,在满足以下条件下,可以使用 document.domain 实现跨域通信:

    • A 页面有 B 页面 window 对象
    • 两个页面的二级域名相同
    • 两个页面协议相同
    • 两个页面端口相同
  • 使用方法

    1、A 获取 B 页面的 window 对象

    • 方法1

      A 页面中 const windowB = window.open(B);

    • 方法2

      A 页面中加入 iframe src=B

      const windowB = window.frames[0].contentWindow;

    2、A 页面 和 B 页面 均设置为相同的 document.domain

    • document.domain 默认是该页面的当前域名
    • document.domain 只能设置为二级域名

    3、A 页面就可以直接访问 B 页面的 window 的内容了

window.name

  • 背景

    同一个窗口,如果页面 A 更新为页面 B,window.name 是不会变的。

  • 使用方法

    1、A 页面嵌入 iframe src=B

    2、B 资源 onload 时,设置 window.name = data;

    3、下一步,A 就要获取 B 设置的 window.name 了。但 A 是无法访问 B 的 iframecontentWindow 信息的。因为 A 和 B 是跨域的。

    4、js 修改 iframe src="about: blank;"(而此时 contentWindow.name 没有变化)。因为 about:blank; 的页面会继承父页面的源,所以 A 页面就能访问 iframe 的 contentWindow 了。这样 A 页面就获取到了信息。

HTML5 postMessage

  • 使用条件:无

  • 使用方法

    • A 页面获取 B 页面的 window 对象 windowB(通过 iframe src=Bwidnow.open(B) 均可)

    • B 页面监听信息

      window.addEventListener('message', function(e) {
      	consoel.log(e);
      });
      

      回调函数里,比较有用的是:

      • e.data
      • e.origin (string)
      • e.source (obj),可以 e.source.postMessage(message, e.origin) 对 A 页面回传信息
    • A 页面发送信息

      windowB.postMessage(message, B)

注意

规范中,规定 message 可以是字符串和其他基本类型,但不同浏览器实现的程度不同,尽量通过 JSON.stringify() 序列化。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions