I'm working on a chrome devtools panels extension. In it I have:
const toDbBtn = document.getElementById("toDbBtn");
toDbBtn.addEventListener("click", async () => {
const dbName = document.getElementById("textBox").value;
// const result = await chrome.storage.local.get(["yourKey"]);
const storedJSON = await chrome.storage.local.get(["yourKey"]);
console.log("Result from storage:", storedJSON);
if (storedJSON.yourKey) {
const parsedArray = JSON.parse(storedJSON.yourKey);
console.log("Parsed Array:", parsedArray);
const partArray = parsedArray.slice(0, 30);
console.log("partArray", partArray);
const data = {
dbName: dbName,
savedArray: partArray,
};
const postable = JSON.stringify(data);
console.log("postable", postable);
// http://localhost:8888/.netlify/functions//updateCollection.js
const response = await fetch(
"http://localhost:8888/.netlify/functions/updateCollection",
{
method: "POST",
headers: {
"Content-Type": "application/json",
// "Access-Control-Allow-Origin": "*",
// "Access-Control-Allow-Methods": "POST",
// "Access-Control-Allow-Headers": "Content-Type",
},
body: postable,
}
);
const result = await response.json();
console.log("Response from server:", result);
} else {
console.log("Value not found in storage for key: yourKey");
}
});
I'm planning to send some data to a netlify function, and so decided to test locally using "NTL DEV" command.
my target ntl function is:
exports.handler = async function (event, context) {
const obj = JSON.parse(event.body);
console.log("obj: ", obj); \
const collectionName = obj.dbName;
const objArray = obj.savedArray;
console.log("objArray: ", objArray);
console.log("collectionName: ", collectionName);
return {
statusCode: 200,
body: JSON.stringify({
message: data,
}),
};
};
When I push the devtools button, I get:
Request from ::ffff:127.0.0.1: OPTIONS /.netlify/functions/updateCollection
based on CORS error while sending request from Browser to play server even after sending CORS header , I assume that the browser starts of by sending a OPTIONS request. But I'm not sure based on https://cli.netlify.com/commands/dev/ how to set a cors header like "Access-Control-Allow-Origin": "*" . How can I get this working?
EDIT:
I have come up with the code below, which appears to handle the original problem, but still has a CORS problem. I'll ask a follow up question.
exports.handler = async function (event, context) {
console.log("context: ", context);
console.log("event: ", event);
if (event.httpMethod !== "OPTIONS" && event.httpMethod !== "POST") {
console.log("event.httpMethod: ", event.httpMethod);
return {
statusCode: 405,
body: JSON.stringify({ message: "Method Not Allowed" }),
};
} else if (event.httpMethod === "OPTIONS") {
return {
statusCode: 204,
headers: headers,
body: null,
};
}
if (event.httpMethod === "POST") {
console.log("event.httpMethod: ", event.httpMethod);
console.log("event.body: ", event.body);
const data = JSON.parse(event.body);
console.log("data: ", data);
}
You'll have to handle the OPTIONS
request and send Access-Control-Allow-Origin:<origin>
header in the OPTIONS
preflight request. See Why does Fetch API Send the first PUT request as OPTIONS.
Something like this using a Node.js HTTP/2 server https://gist.github.com/guest271314/c56d769bca04d92dc941c04d9ac40ba5
const headers = {
"Cache-Control": "no-cache",
"Content-Type": "text/plain; charset=UTF-8",
"Cross-Origin-Opener-Policy": "unsafe-none",
"Cross-Origin-Embedder-Policy": "unsafe-none",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Private-Network": "true",
"Access-Control-Allow-Headers": "Access-Control-Request-Private-Network",
"Access-Control-Allow-Methods": "OPTIONS,POST,GET,HEAD,QUERY,query",
};
// ...
(async () => {
for await (const { request, response } of requestStream) {
if (request.method === "OPTIONS") {
response.writeHead(204, headers);
continue;
}
if (request.method === "POST" || /query/i.test(request.method)) {
response.writeHead(200, headers);
}
// ...
Something like this using Deno Deploy https://gist.github.com/guest271314/c56d769bca04d92dc941c04d9ac40ba5
const responseInit = {
headers: {
'Cache-Control': 'no-cache',
'Content-Type': 'text/plain; charset=UTF-8',
'Cross-Origin-Opener-Policy': 'unsafe-none',
'Cross-Origin-Embedder-Policy': 'unsafe-none',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Private-Network': 'true',
'Access-Control-Allow-Headers': 'Access-Control-Request-Private-Network',
'Access-Control-Allow-Methods': 'OPTIONS,POST,GET,HEAD,QUERY',
},
};
for await (
const conn of Deno.listen({
alpnProtocols: ["h2", "http/1.1"],
})
) {
for await (const {
request,
respondWith
}
of Deno.serveHttp(conn)) {
if (request.method === 'OPTIONS' || request.method === 'HEAD') {
respondWith(new Response(null, responseInit));
}
// ...
Since you're on Chrome I would suggest to take a look at this https://github.com/explainers-by-googlers/local-network-access and https://github.com/explainers-by-googlers/local-network-access/issues/2 re Access-Control-Allow-Private-Network: true
header see https://developer.chrome.com/blog/private-network-access-preflight. Some folks in Google world are proposing adding a property to WHATWG Fetch implementation just for local usage. I don't think it's necessary. Chime in if you are an interested Chromium and or WHATWG Fetch and Streams developer/hacker.