CORS 和安全属性

了解 Nuxt 脚本如何处理跨域安全。

背景

当从外部域加载脚本时,浏览器会强制执行跨源资源共享(CORS)策略。CORS 控制一个域上的资源如何被另一个域运行的脚本请求。对于第三方脚本,这影响:

  • 是否随请求发送 cookie
  • 访问错误详情以便调试
  • 子资源完整性(SRI)验证

默认行为

Nuxt 脚本对所有脚本应用以隐私为中心的默认设置:

<script
  src="https://example.com/script.js"
  crossorigin="anonymous"
  referrerpolicy="no-referrer"
></script>

这些默认设置:

  • crossorigin="anonymous" - 阻止脚本向第三方服务器发送 cookie
  • referrerpolicy="no-referrer" - 阻止向第三方服务器共享页面 URL

这提高了用户隐私,但可能会导致需要 cookie 或来源信息的脚本无法正常工作。

常见 CORS 错误

脚本加载失败

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource

当服务器未返回正确的 CORS 头,而设置了 crossorigin="anonymous" 时会发生此情况。一些第三方脚本不支持 CORS。

脚本加载但功能失败

脚本加载了但功能损坏,因为它期望有 cookie 或会话数据。

错误详情被隐藏

window.onerror = (msg) => console.log(msg)
// 显示为:“Script error.” 而非实际错误信息

没有设置 crossorigin,浏览器出于安全考虑会隐藏来自外部脚本的错误细节。

配置 CORS 属性

针对单个脚本的配置

禁用不支持 CORS 属性的脚本:

useScript({
  src: 'https://example.com/script.js',
  crossorigin: false, // 移除 crossorigin 属性
  referrerpolicy: false, // 移除 referrerpolicy 属性
})

或者使用不同的 crossorigin 值:

useScript({
  src: 'https://example.com/script.js',
  crossorigin: 'use-credentials', // 发送请求时带上 cookie
})

全局配置

更改所有脚本的默认值:

nuxt.config.ts
export default defineNuxtConfig({
  scripts: {
    defaultScriptOptions: {
      crossorigin: false,
      referrerpolicy: false,
    }
  }
})

Crossorigin 值说明

是否发送 cookie是否显示错误详情使用场景
anonymous是(如果服务器支持)注重隐私的默认值
use-credentials需要身份验证的脚本
false不支持 CORS 的脚本

注册脚本

许多注册脚本已禁用 CORS 属性,因为对应的第三方不支持:

// 来自 useScriptStripe
scriptInput: {
  src: 'https://js.stripe.com/basil/stripe.js',
  crossorigin: false,
  referrerpolicy: false,
}

设置 crossorigin: false 的脚本包括:

  • Stripe
  • YouTube 播放器
  • Google 登录
  • Google reCAPTCHA
  • Meta Pixel
  • TikTok Pixel
  • X(Twitter)Pixel
  • Snapchat Pixel
  • Cloudflare Web Analytics
  • Lemon Squeezy
  • Matomo Analytics

如果注册脚本失败,请检查是否需要调整 CORS 配置。

子资源完整性

使用打包脚本并启用 SRI时,crossorigin="anonymous" 是必需的,并会被自动添加:

nuxt.config.ts
export default defineNuxtConfig({
  scripts: {
    assets: {
      integrity: true, // 会自动设置 crossorigin="anonymous"
    }
  }
})

故障排除

脚本无法加载

  1. 检查浏览器控制台中的 CORS 错误
  2. 设置 crossorigin: false 来禁用 CORS 模式
  3. 验证第三方服务器是否支持 CORS 头

脚本加载但功能异常

  1. 脚本可能需要 cookie — 尝试 crossorigin: 'use-credentials'
  2. 脚本可能需要来源信息 — 设置 referrerpolicy: false
  3. 检查脚本是否预期不带 CORS 属性加载

调试外部脚本错误

查看外部脚本的完整错误信息步骤:

  1. 确保脚本有 crossorigin="anonymous"
  2. 验证服务器返回了 Access-Control-Allow-Origin
  3. 如果服务器不支持 CORS,将无法获得详细错误

使用打包作为备选方案

如果 CORS 问题持续存在,可以考虑打包脚本,将其托管在自己的域名下,从而完全避免 CORS 问题。