跨域问题及解决方案详解
字数 1357 2025-11-04 20:48:20

跨域问题及解决方案详解

描述:跨域问题是由浏览器的同源策略引起的一种安全限制。当网页的协议、域名或端口与请求的目标资源不一致时,浏览器会阻止此类跨域请求的响应数据,即使服务器成功响应了请求。

核心概念:同源策略
同源策略要求以下三者必须完全相同:

  • 协议(如 http / https)
  • 域名(如 www.example.com)
  • 端口(如 80 / 443)

解决方案详解

1. JSONP(JSON with Padding)

  • 原理:利用 <script> 标签没有跨域限制的特性,通过动态创建 script 标签来获取数据。
  • 步骤
    1. 前端定义全局回调函数(如 handleResponse)。
    2. 动态创建 <script> 标签,其 src 属性包含请求的 URL 和回调函数名(如 ?callback=handleResponse)。
    3. 服务器接收到请求后,将数据作为参数传递给回调函数,返回如 handleResponse({"data": "value"}) 的脚本。
    4. 浏览器执行该脚本,触发前端定义的回调函数。
  • 局限:仅支持 GET 请求,安全性较低。

2. CORS(跨域资源共享)

  • 原理:W3C 标准,通过服务器设置 HTTP 响应头来显式允许某些跨域请求。
  • 简单请求与非简单请求
    • 简单请求:满足特定条件(如 GET/POST/HEAD,Content-Type 为特定值)。浏览器自动在请求头添加 Origin 字段,服务器需返回 Access-Control-Allow-Origin: * 或具体域名。
    • 非简单请求(如 PUT/DELETE 或自定义头):浏览器先发送 OPTIONS 预检请求,询问服务器是否允许实际请求。服务器需响应 Access-Control-Allow-Methods(允许的方法)和 Access-Control-Allow-Headers(允许的头字段)等。预检通过后,浏览器才发送实际请求。
  • 关键头字段
    • Access-Control-Allow-Origin:允许的源。
    • Access-Control-Allow-Credentials:是否允许发送 Cookie。
    • Access-Control-Expose-Headers:允许前端访问的响应头。

3. 代理服务器

  • 原理:利用服务器之间没有同源限制的特性,由前端服务器代理转发请求至目标服务器。
  • 实现方式
    • 开发环境:使用 webpack-dev-server 的 proxy 配置,将特定 API 请求转发至后端服务器。
    • 生产环境:通过 Nginx 配置反向代理,将跨域请求路径映射到目标服务器。

4. 其他方案

  • postMessage:用于跨窗口通信(如 iframe 与父页面),可安全地传递数据。
  • WebSocket:协议本身支持跨域,但需服务器支持。
  • 修改 document.domain:仅适用于主域相同、子域不同的场景,需双方页面同时设置相同的主域。

总结:CORS 是当前最主流和安全的解决方案,JSONP 适用于旧浏览器或简单场景,代理服务器常见于开发环境。选择方案时需考虑浏览器兼容性和安全性要求。

跨域问题及解决方案详解 描述 :跨域问题是由浏览器的同源策略引起的一种安全限制。当网页的协议、域名或端口与请求的目标资源不一致时,浏览器会阻止此类跨域请求的响应数据,即使服务器成功响应了请求。 核心概念:同源策略 同源策略要求以下三者必须完全相同: 协议(如 http / https) 域名(如 www.example.com) 端口(如 80 / 443) 解决方案详解 1. JSONP(JSON with Padding) 原理 :利用 <script> 标签没有跨域限制的特性,通过动态创建 script 标签来获取数据。 步骤 : 前端定义全局回调函数(如 handleResponse )。 动态创建 <script> 标签,其 src 属性包含请求的 URL 和回调函数名(如 ?callback=handleResponse )。 服务器接收到请求后,将数据作为参数传递给回调函数,返回如 handleResponse({"data": "value"}) 的脚本。 浏览器执行该脚本,触发前端定义的回调函数。 局限 :仅支持 GET 请求,安全性较低。 2. CORS(跨域资源共享) 原理 :W3C 标准,通过服务器设置 HTTP 响应头来显式允许某些跨域请求。 简单请求与非简单请求 : 简单请求 :满足特定条件(如 GET/POST/HEAD,Content-Type 为特定值)。浏览器自动在请求头添加 Origin 字段,服务器需返回 Access-Control-Allow-Origin: * 或具体域名。 非简单请求 (如 PUT/DELETE 或自定义头):浏览器先发送 OPTIONS 预检请求,询问服务器是否允许实际请求。服务器需响应 Access-Control-Allow-Methods (允许的方法)和 Access-Control-Allow-Headers (允许的头字段)等。预检通过后,浏览器才发送实际请求。 关键头字段 : Access-Control-Allow-Origin :允许的源。 Access-Control-Allow-Credentials :是否允许发送 Cookie。 Access-Control-Expose-Headers :允许前端访问的响应头。 3. 代理服务器 原理 :利用服务器之间没有同源限制的特性,由前端服务器代理转发请求至目标服务器。 实现方式 : 开发环境 :使用 webpack-dev-server 的 proxy 配置,将特定 API 请求转发至后端服务器。 生产环境 :通过 Nginx 配置反向代理,将跨域请求路径映射到目标服务器。 4. 其他方案 postMessage :用于跨窗口通信(如 iframe 与父页面),可安全地传递数据。 WebSocket :协议本身支持跨域,但需服务器支持。 修改 document.domain :仅适用于主域相同、子域不同的场景,需双方页面同时设置相同的主域。 总结 :CORS 是当前最主流和安全的解决方案,JSONP 适用于旧浏览器或简单场景,代理服务器常见于开发环境。选择方案时需考虑浏览器兼容性和安全性要求。