标准答案

  1. 同源指协议、域名、端口三者都相同。同源策略限制页面脚本读取不同源响应内容、操作不同源 DOM、读取某些跨源存储,目的是减少恶意页面窃取用户数据。
  2. 同源策略不是禁止所有跨源加载。img、script、link 等标签可以跨源加载资源,但页面脚本不能随意读取跨源接口响应内容。
  3. CORS 是现代跨域 API 的主要方案。服务器通过 Access-Control-Allow-Origin 等响应头明确允许某些源读取响应;复杂请求会先发 OPTIONS 预检。
  4. JSONP 利用 script 标签可跨源执行脚本的特点,只支持 GET,错误处理弱,也不适合敏感数据。postMessage 用于窗口、iframe、Worker 等上下文通信,接收方必须校验 origin 和消息结构。

题目解析

CORS 是否成功不是前端单方面决定的。前端可以设置请求方式、headers、credentials,但浏览器最终会根据服务端响应头决定脚本能不能读取响应。

携带 Cookie 的跨域请求需要前端设置 credentials,服务端也要明确允许凭证,并且 Access-Control-Allow-Origin 不能使用通配星号。

postMessage 的安全关键是校验 event.origin。只校验 message 内容不够,因为任何能拿到窗口引用的页面都可能发送消息。

代码示例

下面示例展示跨域请求携带凭证,以及 postMessage 接收方校验来源。

JavaScript
fetch('https://api.example.com/profile', {
  credentials: 'include'
})
  .then((response) => {
    if (!response.ok) {
      throw new Error('HTTP ' + response.status)
    }

    return response.json()
  })

window.addEventListener('message', (event) => {
  if (event.origin !== 'https://trusted.example.com') {
    return
  }

  if (event.data?.type === 'AUTH_DONE') {
    console.log('登录完成')
  }
})

常见误区

  • 误以为 CORS 是前端单方面能解决的问题。
  • JSONP 用在非 GET 或敏感数据场景。
  • postMessage 不校验 origin,造成安全风险。

作者信息