JavaScript 跨域解决方案汇总:从 JSONP 到 CORS 的实战指南

作者:纸飞机

时间:2026-10-29

浏览:316

本文汇总了 JavaScript 中常见的六种跨域解决方案,包括利用 script 标签的 JSONP、HTML5 的 postMessage、基于 window.name 和 location.hash 的 iframe 方案,以及现代浏览器支持的 CORS 和 document.domain。通过具体代码示例,详细解析了各方案的实现原理、适用场景及注意事项,帮助开发者根据实际需求选择最合适的跨域策略。

文章目录

JavaScript 跨域解决方案汇总

本文参考了其他前端开发者的经验,并结合实际案例进行了整理与总结。

示例中涉及的文件地址分别为 http://www.a.com/a.html、http://www.a.com/c.html 以及 http://www.b.com/b.html,主要目标是从 a.html 获取 b.html 中的数据。

JSONP 方案

1. JSONP

JSONP 利用 script 标签不受跨域限制的特性,通过在 src 属性的 URL 中附加回调函数名,服务器接收该名称后返回包含数据的回调函数调用。


  function doSomething(data) {
    // 对data处理
  }
  var script = document.createElement("script");
  script.src = "http://www.b.com/b.html?callback=doSomething";
  document.body.appendChild(script);

  // 1.生成一个script标签,将其append在body上,向服务器发出请求
  // 2.服务器根据 callback 这个参数生成一个包含数据的函数 doSomething({"a", "1"})
  // 3.页面事先已声明doSomething函数,此时执行 doSomething(data) 这个函数,获得数据

HTML5 postMessage 方案

2. HTML5 的 postMessage

假设在 a.html 中嵌套了一个 <iframe src="http://www.b.com/b.html" frameborder="0"></iframe>,实现这两个页面之间的双向通信。

a.html


  window.onload = function() {
    window.addEventListener("message", function(e) {
      alert(e.data);
    });

    window.frames[0].postMessage("b data", "http://www.b.com/b.html");
  }

b.html


  window.onload = function() {
    window.addEventListener("message", function(e) {
      alert(e.data);
    });
    window.parent.postMessage("a data", "http://www.a.com/a.html");
  }

打开 a 页面后,会依次弹出 'a data' 和 'b data'。

window.name 与 iframe 方案

3. window.name + iframe

window.name 的原理是利用同一窗口在不同页面间共享 window.name 属性。这需要在 a.com 下建立一个代理文件 c.html,使 a.html 与 c.html 同源后,a.html 即可获取 c.html 的 window.name。

a.html


  var iframe = document.createElement("iframe");
  iframe.src = "http://www.b.com/b.html";
  document.body.appendChild(iframe); // 现在a.html里建一个引用b.html的iframe,获得b的数据

  var flag = true;
  iframe.onload = function() {
    if (flag) {
      iframe.src = "c.html"; 
// 判断是第一次载入的话,设置代理c.html使和a.html在同目录同源,这样才能在下面的else取到data
      flag = false;
    } else { // 第二次载入由于a和c同源,a可以直接获取c的window.name
      alert(iframe.contentWindow.name);

      iframe.contentWindow.close();
      document.body.removeChild(iframe);
      iframe.src = '';
      iframe = null;
    }
  }

b.html


window.name = "这是 b 页面的数据";

location.hash 与 iframe 方案

4. window.location.hash + iframe

b.html 将数据以 hash 值的形式附加到 c.html 的 URL 上,c.html 页面通过 location.hash 获取数据后,再将其传递回 a.html(本例中传递到 a.html 的 hash 上,也可传递至其他位置)。

a.html


  var iframe = document.createElement("iframe");
  iframe.src = "http://www.b.com/b.html";
  document.body.appendChild(iframe); // 在a页面引用b
  function check() { // 设置个定时器不断监控hash的变化,hash一变说明数据传过来了
    var hashs = window.location.hash;
    if (hashs) {
      clearInterval(time);
      alert(hashs.substring(1));
    }
  }
  var time = setInterval(check, 30);

b.html


  window.onload = function() {
    var data = "this is b's data"; 
    var iframe = document.createElement("iframe");
    iframe.src = "http://www.a.com/c.html#" + data;
    document.body.appendChild(iframe); // 将数据附加在c.html的hash上
  }

c.html


// 获取自身的hash再传到a.html的hash里,数据传输完毕
parent.parent.location.hash = self.location.hash.substring(1); 

CORS 方案

5. CORS

CORS 是 XMLHttpRequest Level 2 规范定义的一种跨域方式。在支持该规范的浏览器中,JavaScript 的写法与不跨域的 AJAX 完全一致,只需服务器设置 Access-Control-Allow-Origin: * 即可。

document.domain 方案

6. document.domain

此方法适用于主域相同但子域不同的场景,例如 http://www.a.com 和 http://b.a.com。假设这两个域名下分别有 a.html 和 b.html。

a.html


  document.domain = "a.com";
  var iframe = document.createElement("iframe");
  iframe.src = "http://b.a.com/b.html";
  document.body.appendChild(iframe);
  iframe.onload = function() {
    console.log(iframe.contentWindow....); // 在这里操作b.html里的元素数据
  }

b.html


  document.domain = "a.com";

注意:document.domain 必须设置为自身或更高一级的父域,且主域必须保持一致。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章