You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Web Component嵌入遭CORS拦截,Vercel配置无效求解决方案

问题

我用r2wc/react-to-web-component创建了一个React Web Component,部署在Vercel平台,访问地址为https://<my-project-name>.vercel.app/assets/js/widget.js。

尝试在Next.js项目(也测试过纯HTML页面)中通过以下脚本嵌入该组件:

export default function Home() {
    useEffect(() => {
        const script = document.createElement('script');
        script.src = 'https://<my-project-name>.vercel.app/assets/js/widget.js';
        script.type = 'module';
        script.async = true;
        script.id = 'widget';
        document.body.appendChild(script);
    
        return () => {
          document.body.removeChild(script);
        };
      }, []);

  return <widget></widget>;
};

但出现CORS报错:

Access to script at 'https://.vercel.app/assets/js/widget.js' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

组件逻辑仅返回<></> Hello </>,本地构建运行正常。我已在导出组件的应用中添加vercel.json配置CORS响应头,内容如下:

{
    "rewrites": [
      {
        "source": "/:path*",
        "destination": "/"
      }
    ],
    "headers": [
      {
        "source": "/assets/js/widget.js",
        "headers": [
          {
            "key": "Access-Control-Allow-Origin",
            "value": "*"
          },
          {
            "key": "Access-Control-Allow-Methods",
            "value": "GET, HEAD, OPTIONS"
          },
          {
            "key": "Access-Control-Allow-Headers",
            "value": "Content-Type" 
          }
        ]
      }
    ],
    "git": {
      "deploymentEnabled": {
        "master": false,
        "development": false
      }
    }
  }

我的需求是允许任意域名访问该组件,但问题未解决,想知道遗漏了什么配置,该如何解决?


解决方法

1. 确认Vercel配置已部署生效

修改vercel.json后必须重新部署Vercel项目,确保配置被读取。可通过Vercel控制台部署记录确认最新版本包含更新后的配置文件。

同时用curl命令直接请求脚本地址,检查响应头是否存在Access-Control-Allow-Origin:

curl -I https://<my-project-name>.vercel.app/assets/js/widget.js

如果响应头中没有该字段,说明配置未生效,需排查部署流程。

2. 修正路径匹配规则

Vercel的source路径匹配可能因静态资源实际生成路径(如带哈希后缀、目录结构变化)失效,可改用通配符匹配所有JS文件:

{
  "headers": [
    {
      "source": "/assets/js/*.js",
      "headers": [
        {
          "key": "Access-Control-Allow-Origin",
          "value": "*"
        },
        {
          "key": "Access-Control-Allow-Methods",
          "value": "GET, HEAD, OPTIONS"
        },
        {
          "key": "Access-Control-Allow-Headers",
          "value": "Content-Type"
        }
      ]
    }
  ],
  "rewrites": [
    {
      "source": "/:path*",
      "destination": "/"
    }
  ],
  "git": {
    "deploymentEnabled": {
      "master": false,
      "development": false
    }
  }
}

3. 验证OPTIONS预检请求响应

module类型脚本会触发浏览器OPTIONS预检请求,需确保Vercel正确返回CORS头。虽然你已配置Access-Control-Allow-Methods包含OPTIONS,但需确认该配置实际生效。

4. 核对静态资源实际路径

确认构建后的widget.js确实存在于/assets/js/路径下。部分React项目构建后静态资源会放在/static/或带哈希的子目录中,需根据实际输出调整vercel.json的source路径。

5. 边缘函数兜底方案

若上述方法无效,可创建Vercel边缘函数代理脚本并强制添加CORS头:

  1. 在项目根目录创建api/proxy-widget.js:
export default async function handler(req) {
  const widgetUrl = new URL('/assets/js/widget.js', `https://${process.env.VERCEL_URL}`);
  const response = await fetch(widgetUrl);
  const headers = new Headers(response.headers);
  headers.set('Access-Control-Allow-Origin', '*');
  headers.set('Access-Control-Allow-Methods', 'GET, HEAD, OPTIONS');
  headers.set('Access-Control-Allow-Headers', 'Content-Type');
  
  return new Response(response.body, {
    status: response.status,
    headers: headers
  });
}

export const config = {
  runtime: 'edge',
};
  1. 嵌入时使用代理地址:https://<my-project-name>.vercel.app/api/proxy-widget.js

内容的提问来源于stack exchange,提问作者smaica

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 19:37:36