24.跨域 手写 JSONP

书诚小驿2025/02/25前端面经Javascript

跨域的产生原因

同源策略:浏览器出于安全考虑,限制不同源的页面间资源交互。

同源定义:协议(http/https)、域名(www.example.com)、端口(8080)三者完全一致。

触发跨域的场景:

AJAX 请求不同源的 API

Web 字体、WebGL 等资源加载。

iframe 嵌入不同源页面并尝试通信。

跨域常见解决方案

方案一:CORS(跨域资源共享) 原理:服务端通过响应头声明允许的跨域请求来源、方法及头部。

Access-Control-Allow-Origin: https://www.example.com  // 允许的源(或 * 表示所有)
Access-Control-Allow-Methods: GET, POST, PUT         // 允许的请求方法
Access-Control-Allow-Headers: Content-Type, X-Token  // 允许的请求头
Access-Control-Allow-Credentials: true              // 允许携带 Cookie

方案二:反向代理 原理:通过同源的服务端代理转发请求,避开浏览器限制。 开发环境:使用 WebpackdevServer.proxyViteserver.proxy

生产环境:通过 Nginx 配置反向代理。

方案三:JSONP 原理:利用 <script> 标签不受同源策略限制的特性,通过回调函数获取数据。

function jsonp(url, callbackName) {
  const script = document.createElement("script");
  script.src = `${url}?callback=${callbackName}`;
  document.body.appendChild(script);
}

// 服务端返回:callbackName({ data: ... });
window.handleData = (data) => {
  console.log("Received:", data);
};
jsonp("https://api.example.com/data", "handleData");

方案四:WebSocket 原理:WebSocket 协议不受同源策略限制。

const socket = new WebSocket("wss://api.example.com");
socket.onmessage = (event) => {
  console.log("Data:", event.data);
};

方案五:postMessage 原理:postMessage 方法不受同源策略限制,可用于不同源的页面间通信。

// 父页面
window.frames[0].postMessage("Hello", "https://child.com");

// 子页面(iframe)
window.addEventListener("message", (event) => {
  if (event.origin !== "https://parent.com") return;
  console.log("Received:", event.data);
});
最后更新时间' 2025/3/25 07:37:15