JavaScript的同源策略

49 阅读2分钟

JavaScript的同源策略

JavaScript 的同源策略(Same-Origin Policy) 是浏览器最核心的安全机制之一,目的是防止恶意网站通过脚本或请求窃取用户数据或发起攻击。它的核心规则是:浏览器只允许脚本访问与当前页面「同源」的资源

一、什么是「同源」?

两个 URL 的以下三个部分必须完全一致:

  1. 协议(Protocol,如 http vs https
  2. 域名(Domain,如 example.com vs sub.example.com
  3. 端口(Port,如 80 vs 8080,默认端口可省略)

示例:

当前页面 URL目标 URL是否同源原因
https://example.com/ahttps://example.com/b协议、域名、端口均一致
http://example.comhttps://example.com协议不同(HTTP vs HTTPS)
https://example.comhttps://api.example.com域名不同(主域 vs 子域)
https://example.com:80https://example.com:443端口不同

二、同源策略的限制范围

  1. AJAX / Fetch 请求

    • 默认禁止跨域请求(如 fetch("https://api.other.com") 会被浏览器拦截)。
    • 需通过 CORS 或代理等方式解决。
  2. DOM 访问

    • 禁止跨域访问 iframe 或新窗口的内容(如 window.parent.document)。
  3. Web 存储

    • CookieLocalStorageIndexedDB 仅允许同源访问。
  4. 其他资源加载

    • 虽然 <img><script><link> 等标签允许跨域加载资源(如 CDN 引用),但无法直接读取跨域资源的内容(例如通过 JavaScript 读取跨域图片的像素数据)。

三、如何绕过同源策略?

  1. CORS(跨域资源共享)
  • 原理:服务器在响应头中声明允许的跨域来源。
  • 实现
    Access-Control-Allow-Origin: https://your-site.com  # 允许特定源
    Access-Control-Allow-Origin: *                     # 允许所有源(慎用!)
    
  • 复杂请求(如 POST 带自定义头):需预检(Preflight)请求(OPTIONS 方法)。
  1. JSONP(仅限 GET 请求)
  • 原理:利用 <script> 标签不受同源策略限制的特性,通过回调函数接收数据。

  • 示例

    <script src="https://api.other.com/data?callback=handleData"></script>
    
    function handleData(data) {
      console.log("Received:", data);
    }
    
  1. 代理服务器
  • 原理:通过同源的后端服务器转发跨域请求(如 Nginx 或 Node.js 代理)。
  • 适用场景:无法修改目标服务器(如第三方 API)时使用。
  1. postMessage API
  • 原理:允许跨域的窗口间通过消息传递通信。
  • 示例
    // 发送消息到其他窗口
    otherWindow.postMessage("Hello!", "https://other-site.com");
    
    // 接收消息
    window.addEventListener("message", (event) => {
      if (event.origin === "https://other-site.com") {
        console.log("Received:", event.data);
      }
    });
    
  1. WebSocket
  • 原理:WebSocket 协议默认支持跨域通信(但服务器需验证 Origin 头)。

四、注意事项

  • 安全风险:过度放宽跨域限制(如 Access-Control-Allow-Origin: *)可能导致 CSRF 或数据泄露。
  • Cookie 跨域:需设置 withCredentials: true(前端)和 Access-Control-Allow-Credentials: true(服务端)。
  • 现代浏览器限制:默认禁止跨域的 document.cookieLocalStorage 访问,即使域名相同但协议或端口不同也会被拦截。

总结

同源策略是浏览器安全的基石,但合理使用 CORS、代理、postMessage 等技术可实现安全的跨域通信。开发中需根据场景选择方案,并始终遵循最小权限原则,避免安全漏洞。

更多vue相关插件及后台管理模板可访问vue admin reference,代码详情请访问github