Do i really need cors, can i just not use it, if so, how?
Itâs a browser feature, you can probably disable it but it would be only for your browser, not for your users.
To solve CORS you have to make your API accept requests coming from the domain of your project (weweb domain while editing or using preview, your domain once published).
If you donât have the hand on the API and the service donât provide a way to enter a kind of domain whitelist, then you can still use our proxy toggle on collection and rest api action, we will perform the request server side to bypass CORS.
But be aware, if you have a CORS issue and canât resolve it through an API/service configuration, it probably mean the API is not made to be accessed from a browser/frontend.
If the API require a private api key to be accessed, then you shouldnât made the request from your frontend at all.
Okey, it has to work for all browser, to explain my case in short i have weweb as front end, supabase as back end, and a script that is deployed as an edge function in supabase. I have cors headers in this script:
âAccess-Control-Allow-Originâ: âhttps://editor.weweb.ioâ,
âAccess-Control-Allow-Methodsâ: âPOST, OPTIONSâ,
âAccess-Control-Allow-Headersâ: âContent-Type, Authorizationâ,
So its ment for the development mode first, and then Iâll change it to my custom domain later
I ran this same script in my CLI with the open ai API and it worked fine so i know that the connection is working, its just when trying to access it using weweb i have this issue and looks like it is the cors thing.
Anything odd or specific you see or notice that is worng?
Please share the part of the code in your edge function where you are returning the CORS headers
Most of the time the issue is the code doesnât not return the headers for the âOPTIONSâ request method for exemple.
Here it is:
async function handler(req: Request): Promise<Response> {
if (req.method === 'OPTIONS') {
// Handle CORS preflight requests
return new Response(null, {
status: 204,
headers: {
'Access-Control-Allow-Origin': 'https://cdn.weweb.io/components/',
'Access-Control-Allow-Methods': 'POST, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
},
});
}
It should be https://editor.weweb.io
to make your request work in the editor
And for the published one, if you donât have any domain attached yet, you should also add https://<project-id>.weweb-preview.io
Like this: âAccess-Control-Allow-Originâ: âhttps://cdn.weweb.io/components/, https://.weweb-preview.ioâ,
Iâm still expiriencing the same issue after deploying the edge function again to supabase
anything wrong you can see in this screenshot of my invoke edge function?
You added https://cdn.weweb.io/components/
as I said, it should be https://editor.weweb.io
I tried that now, iâm still getting this error: message: âFailed to send a request to the Edge Functionâ
Can you open the console and share the error message please ? The issue should be explained inside
(not the network tab, the console, you should have a message containing something like âhas been blocked by CORS policyâ)
From what I see on the documentation the CORS headers should be returned for both the OPTIONS response and for the final response
As I donât have the whole code Iâm not sure youâre also returning the CORS headers in the final response
Okey
This is from the console:
This is the code in the index.ts file
import { serve } from './deps.ts';
import { Configuration, OpenAIApi } from './deps.ts';
// Initialize the OpenAI API client with the API key from environment variables
const configuration = new Configuration({
apiKey: Deno.env.get('OPENAI_API_KEY'),
});
const openai = new OpenAIApi(configuration);
// Define the handler function for incoming HTTP requests
async function handler(req: Request): Promise<Response> {
if (req.method === 'OPTIONS') {
// Handle CORS preflight requests
return new Response(null, {
status: 204,
headers: {
'Access-Control-Allow-Origin': 'https://editor.weweb.io, https://.weweb-preview.io',
'Access-Control-Allow-Methods': 'POST, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
},
});
}
if (req.method !== 'POST') {
return new Response('Method Not Allowed', { status: 405 });
}
try {
// Hardcoding the image URL as per your instruction
const imageUrl = "https://i.imgur.com/dzb3jEc.png";
const requestBody = {
model: "gpt-4o",
messages: [
{
role: "user",
content: [
{ type: "text", text: "Whatâs in this image?" },
{
type: "image_url",
image_url: { url: imageUrl }
}
]
}
]
};
const response = await fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${Deno.env.get('OPENAI_API_KEY')}`,
},
body: JSON.stringify(requestBody),
});
if (!response.ok) {
const errorDetails = await response.text();
return new Response(`Failed to analyze the image: ${response.status} ${response.statusText} - ${errorDetails}`, {
status: 500,
headers: {
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json',
},
});
}
const responseData = await response.json();
const result = responseData.choices[0].message.content;
// Prettify the result
const prettifiedResult = result.split('\n').map(line => line.trim()).join('\n');
return new Response(JSON.stringify({ result: prettifiedResult }), {
status: 200,
headers: {
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json',
},
});
} catch (error) {
return new Response(`Failed to analyze the image: ${error.message}`, {
status: 500,
headers: {
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json',
},
});
}
}
// Start the server and listen for requests
serve(handler);
The message is saying you have two values but only one is allowed.
So you can try to keep only https://editor.weweb.io and it should works for the editor.
As you also need to authorise the published app you may prefer use the â*â instead of specifying a domain. This is what youâre doing in the response headers below.
You also need to add the 'Access-Control-Allow-Headers': 'Content-Type, Authorization',
line in your headers response, itâs missing
return new Response(JSON.stringify({ result: prettifiedResult }), {
status: 200,
headers: {
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json',
// MISSING Access-Control-Allow-Headers
},
});
I changed it to this now âAccess-Control-Allow-Originâ: â*â
Iâm not following 100% on the second part
this is my current code it has the Access-Control-Allow-Origin, Access-Control-Allow-Methods and Access-Control-Allow-Headers. It has the Access-Control-Allow-Headers with content-type and Auth
but not the: âContent-Typeâ: âapplication/jsonâ, that you are providing above, is that the only line I need to add to my current code?
return new Response(null, {
status: 204,
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
},
});
This is the Response to the OPTIONS request, but you also have to add it on the Response of the POST request, and in the Response in the catch too.
Every time you create a new Response, you should add the same CORS headers
If you search ânew Responseâ in your code, you have 5 lines where you create a Response, but only the first one has the correct headers with the âAccess-Control-Allow-Headersâ
Okey, that makes sense
Iâve added the ACAH header now to the ones missing it
import { serve } from './deps.ts';
import { Configuration, OpenAIApi } from './deps.ts';
// Initialize the OpenAI API client with the API key from environment variables
const configuration = new Configuration({
apiKey: Deno.env.get('OPENAI_API_KEY'),
});
const openai = new OpenAIApi(configuration);
// Define the handler function for incoming HTTP requests
async function handler(req: Request): Promise<Response> {
if (req.method === 'OPTIONS') {
// Handle CORS preflight requests
return new Response(null, {
status: 204,
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
},
});
}
if (req.method !== 'POST') {
return new Response('Method Not Allowed', { status: 405 });
}
try {
// Hardcoding the image URL as per your instruction
const imageUrl = "https://i.imgur.com/dzb3jEc.png";
const requestBody = {
model: "gpt-4o",
messages: [
{
role: "user",
content: [
{ type: "text", text: "Whatâs in this image?" },
{
type: "image_url",
image_url: { url: imageUrl }
}
]
}
]
};
const response = await fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${Deno.env.get('OPENAI_API_KEY')}`,
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
},
body: JSON.stringify(requestBody),
});
if (!response.ok) {
const errorDetails = await response.text();
return new Response(`Failed to analyze the image: ${response.status} ${response.statusText} - ${errorDetails}`, {
status: 500,
headers: {
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
},
});
}
const responseData = await response.json();
const result = responseData.choices[0].message.content;
// Prettify the result
const prettifiedResult = result.split('\n').map(line => line.trim()).join('\n');
return new Response(JSON.stringify({ result: prettifiedResult }), {
status: 200,
headers: {
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
},
});
} catch (error) {
return new Response(`Failed to analyze the image: ${error.message}`, {
status: 500,
headers: {
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
},
});
}
}
// Start the server and listen for requests
serve(handler);
But still getting the same error
Itâs not the same error as you can read it. It say âx-client-infoâ is not allowed by your âAccess-Control-Allow-Headersâ header, you can try to add it.
You have the recommended setup provided by the supabase documentation
Now its working, it was the ACAH: needed to contain: Auth, x client, apikey and content type,
Thanks for the help and the patient @Alexis