CORS 策略阻止了 Cloudflare Worker Function
CORS policy blocked Cloudfare Worker Function
我有 cloudfare worker 函数,我试图从我的 React 网络应用程序调用它,但我经常出错
Access to fetch at
'https://xxxxx.workers.dev/' from origin
'http://localhost:8000' 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. If an opaque response serves your needs, set the request's
mode to 'no-cors' to fetch the resource with CORS disabled
我不想使用 no-cors
模式,我试图在 cloudfare 仪表板上找到允许来源域的选项,但似乎找不到。
请问有人知道如何解决这个问题吗?
这是函数代码
addEventListener("fetch", (event) => {
event.respondWith(
handleRequest(event.request).catch(
(err) => new Response(err.stack, { status: 500 })
)
);
});
/**
* Many more examples available at:
* https://developers.cloudflare.com/workers/examples
* @param {Request} request
* @returns {Promise<Response>}
*/
async function handleRequest(request) {
const { pathname } = new URL(request.url);
if (pathname.startsWith("/api")) {
return new Response(JSON.stringify({ pathname }), {
headers: { "Content-Type": "application/json" },
});
}
if (pathname.startsWith("/status")) {
const httpStatusCode = Number(pathname.split("/")[2]);
return Number.isInteger(httpStatusCode)
? fetch("https://http.cat/" + httpStatusCode)
: new Response("That's not a valid HTTP status code.");
}
return new Response({
hello: "world",
});
}
这就是帮助我解决问题的原因:https://community.cloudflare.com/t/worker-site-http-request-to-worker/151529/8
函数代码:
// An example worker which supports CORS. It passes GET and HEAD
// requests through to the origin, but answers OPTIONS and POST
// requests directly. POST requests must contain a JSON payload,
// which is simply echoed back.
addEventListener('fetch', event => {
event.respondWith(handle(event.request)
// For ease of debugging, we return exception stack
// traces in response bodies. You are advised to
// remove this .catch() in production.
.catch(e => new Response(e.stack, {
status: 500,
statusText: "Internal Server Error"
}))
)
})
async function handle(request) {
if (request.method === "OPTIONS") {
return handleOptions(request)
} else if (request.method === "POST") {
return handlePost(request)
} else if (request.method === "GET" || request.method == "HEAD") {
// Pass-through to origin.
return fetch(request)
} else {
return new Response(null, {
status: 405,
statusText: "Method Not Allowed",
})
}
}
// We support the GET, POST, HEAD, and OPTIONS methods from any origin,
// and accept the Content-Type header on requests. These headers must be
// present on all responses to all CORS requests. In practice, this means
// all responses to OPTIONS or POST requests.
const corsHeaders = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, HEAD, POST, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type",
}
function handleOptions(request) {
if (request.headers.get("Origin") !== null &&
request.headers.get("Access-Control-Request-Method") !== null &&
request.headers.get("Access-Control-Request-Headers") !== null) {
// Handle CORS pre-flight request.
return new Response(null, {
headers: corsHeaders
})
} else {
// Handle standard OPTIONS request.
return new Response(null, {
headers: {
"Allow": "GET, HEAD, POST, OPTIONS",
}
})
}
}
async function handlePost(request) {
if (request.headers.get("Content-Type") !== "application/json") {
return new Response(null, {
status: 415,
statusText: "Unsupported Media Type",
headers: corsHeaders,
})
}
// Detect parse failures by setting `json` to null.
let json = await request.json().catch(e => null)
if (json === null) {
return new Response("JSON parse failure", {
status: 400,
statusText: "Bad Request",
headers: corsHeaders,
})
}
return new Response(JSON.stringify(json), {
headers: {
"Content-Type": "application/json",
...corsHeaders,
}
})
}
打电话
const Http = new XMLHttpRequest();
const url='HTTPS://YOUR_CLOUDFLARE_WORKER';
Http.open("POST", url);
Http.setRequestHeader('Accept', 'application/json');
Http.setRequestHeader('Content-Type', 'application/json');
Http.send('{"test": "GP"}');
Http.onreadystatechange = (e) => {
console.log(Http.responseText)
}
我有 cloudfare worker 函数,我试图从我的 React 网络应用程序调用它,但我经常出错
Access to fetch at 'https://xxxxx.workers.dev/' from origin 'http://localhost:8000' 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. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled
我不想使用 no-cors
模式,我试图在 cloudfare 仪表板上找到允许来源域的选项,但似乎找不到。
请问有人知道如何解决这个问题吗?
这是函数代码
addEventListener("fetch", (event) => {
event.respondWith(
handleRequest(event.request).catch(
(err) => new Response(err.stack, { status: 500 })
)
);
});
/**
* Many more examples available at:
* https://developers.cloudflare.com/workers/examples
* @param {Request} request
* @returns {Promise<Response>}
*/
async function handleRequest(request) {
const { pathname } = new URL(request.url);
if (pathname.startsWith("/api")) {
return new Response(JSON.stringify({ pathname }), {
headers: { "Content-Type": "application/json" },
});
}
if (pathname.startsWith("/status")) {
const httpStatusCode = Number(pathname.split("/")[2]);
return Number.isInteger(httpStatusCode)
? fetch("https://http.cat/" + httpStatusCode)
: new Response("That's not a valid HTTP status code.");
}
return new Response({
hello: "world",
});
}
这就是帮助我解决问题的原因:https://community.cloudflare.com/t/worker-site-http-request-to-worker/151529/8
函数代码:
// An example worker which supports CORS. It passes GET and HEAD
// requests through to the origin, but answers OPTIONS and POST
// requests directly. POST requests must contain a JSON payload,
// which is simply echoed back.
addEventListener('fetch', event => {
event.respondWith(handle(event.request)
// For ease of debugging, we return exception stack
// traces in response bodies. You are advised to
// remove this .catch() in production.
.catch(e => new Response(e.stack, {
status: 500,
statusText: "Internal Server Error"
}))
)
})
async function handle(request) {
if (request.method === "OPTIONS") {
return handleOptions(request)
} else if (request.method === "POST") {
return handlePost(request)
} else if (request.method === "GET" || request.method == "HEAD") {
// Pass-through to origin.
return fetch(request)
} else {
return new Response(null, {
status: 405,
statusText: "Method Not Allowed",
})
}
}
// We support the GET, POST, HEAD, and OPTIONS methods from any origin,
// and accept the Content-Type header on requests. These headers must be
// present on all responses to all CORS requests. In practice, this means
// all responses to OPTIONS or POST requests.
const corsHeaders = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, HEAD, POST, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type",
}
function handleOptions(request) {
if (request.headers.get("Origin") !== null &&
request.headers.get("Access-Control-Request-Method") !== null &&
request.headers.get("Access-Control-Request-Headers") !== null) {
// Handle CORS pre-flight request.
return new Response(null, {
headers: corsHeaders
})
} else {
// Handle standard OPTIONS request.
return new Response(null, {
headers: {
"Allow": "GET, HEAD, POST, OPTIONS",
}
})
}
}
async function handlePost(request) {
if (request.headers.get("Content-Type") !== "application/json") {
return new Response(null, {
status: 415,
statusText: "Unsupported Media Type",
headers: corsHeaders,
})
}
// Detect parse failures by setting `json` to null.
let json = await request.json().catch(e => null)
if (json === null) {
return new Response("JSON parse failure", {
status: 400,
statusText: "Bad Request",
headers: corsHeaders,
})
}
return new Response(JSON.stringify(json), {
headers: {
"Content-Type": "application/json",
...corsHeaders,
}
})
}
打电话
const Http = new XMLHttpRequest();
const url='HTTPS://YOUR_CLOUDFLARE_WORKER';
Http.open("POST", url);
Http.setRequestHeader('Accept', 'application/json');
Http.setRequestHeader('Content-Type', 'application/json');
Http.send('{"test": "GP"}');
Http.onreadystatechange = (e) => {
console.log(Http.responseText)
}