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头:
- 在项目根目录创建
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', };
- 嵌入时使用代理地址:
https://<my-project-name>.vercel.app/api/proxy-widget.js
内容的提问来源于stack exchange,提问作者smaica

