JS调用Cloudflare Workers时出现No 'Access-Control-Allow-Origin' header错误
我在Cloudflare Workers上部署了一个JavaScript边缘函数,功能为检查特定请求头并返回对应JSON数据。函数代码如下:
async function handleRequest(request) { const url = new URL(request.url); const psk_db = await KV_STORAGE.get(request.headers.get(PRESHARED_AUTH_HEADER_KEY)); if (psk_db === null) { return new Response("Access denied", { status: 404 }); } else{ //calculate number //return JSON const data = { pswd: psk_db, }; json = JSON.stringify(data, null, 2); } return new Response(json, { headers: { 'content-type': 'application/json;charset=UTF-8', 'Access-Control-Allow-Origin': url.origin, }, }) } addEventListener('fetch', event => { event.respondWith(handleRequest(event.request)); });
通过本地HTML页面的按钮调用以下JavaScript函数发起请求时:
function RequestCode() { const Http = new XMLHttpRequest(); const url = "https://code-return.dev-malv.workers.dev"; Http.open("GET", url); Http.setRequestHeader("Access-Control-Allow-Origin", "*"); Http.setRequestHeader("X-Custom-PSK", "m_custom_key"); Http.send(); Http.onreadystatechange = (e) => { console.log(Http.responseText); }; }
出现如下错误:
Access to XMLHttpRequest at 'my_workers_url' from origin 'null' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
我已尝试在两端设置Access-Control-Allow-Origin: *,但问题仍未解决,请问该如何处理?
1. 处理OPTIONS预检请求
当请求包含自定义头X-Custom-PSK时,浏览器会先发送OPTIONS预检请求验证权限,你的Worker当前未处理这类请求,导致预检失败。需在handleRequest开头添加OPTIONS请求的处理逻辑:
async function handleRequest(request) { // 处理OPTIONS预检请求 if (request.method === 'OPTIONS') { const url = new URL(request.url); return new Response(null, { headers: { 'Access-Control-Allow-Origin': url.origin, // 调试阶段可改为*允许所有源 'Access-Control-Allow-Methods': 'GET, OPTIONS', 'Access-Control-Allow-Headers': 'X-Custom-PSK', // 必须包含自定义请求头 'Access-Control-Max-Age': '86400' // 缓存预检结果,减少重复请求 } }); } // 原有业务逻辑 const url = new URL(request.url); const psk_db = await KV_STORAGE.get(request.headers.get(PRESHARED_AUTH_HEADER_KEY)); if (psk_db === null) { // 错误响应也必须带上CORS头 return new Response("Access denied", { status: 404, headers: { 'Access-Control-Allow-Origin': url.origin } }); } const data = { pswd: psk_db }; const json = JSON.stringify(data, null, 2); return new Response(json, { headers: { 'content-type': 'application/json;charset=UTF-8', 'Access-Control-Allow-Origin': url.origin, }, }); }
2. 移除前端错误的请求头设置
Access-Control-Allow-Origin是服务端返回的响应头,不需要在前端请求中设置,直接删除这行代码:
function RequestCode() { const Http = new XMLHttpRequest(); const url = "https://code-return.dev-malv.workers.dev"; Http.open("GET", url); // 移除错误的头设置:Http.setRequestHeader("Access-Control-Allow-Origin", "*"); Http.setRequestHeader("X-Custom-PSK", "m_custom_key"); Http.send(); Http.onreadystatechange = (e) => { console.log(Http.responseText); }; }
3. 确保所有响应都携带CORS头
包括404等错误响应,必须统一添加Access-Control-Allow-Origin头,否则浏览器会拦截错误响应的CORS检查。生产环境建议限制为特定域名,调试阶段可临时设置为*。
内容的提问来源于stack exchange,提问作者NicoCaldo

