kit
kit copied to clipboard
Method Options - HTTP
Describe the problem
I didn't see the Options method for building APIs. Is it possible to have it?
Describe the proposed solution
It is important to query the server capacity and the Options method, it provides for us
Alternatives considered
No response
Importance
would make my life easier
Additional Information
No response
In addition to the OPTIONS method, HTTP also defines CONNECT and TRACE. TRACE means "please send my request back to me", and if it's going to be handled at all, should be handled by Svelte-Kit itself rather than by page endpoints. CONNECT means "please open a connection to this remote destination and then forward packets for me" and should only be implemented by proxies with appropriate security, and not by Svelte-Kit.
Which leaves only OPTIONS, which could indeed be useful for Svelte-Kit projects that are implementing APIs, and should be added. Currently the node-adapter handles OPTIONS requests and doesn't pass them on to the site. Repro:
- Create a brand-new Svelte-Kit project with the demo app and Typescript
- Create
src/routes/something.tscontaining the following:
import type { RequestHandler } from './__types';
export const get: RequestHandler = async ({ locals }) => {
return { status: 200, body: 'get' }
}
export const options: RequestHandler = async ({ locals }) => {
return { status: 200, body: 'options' }}
- Run
pnpm run dev - Run
curl -D - http://localhost:3000/somethingto verify that the GET method works (and prints "get") - Run
curl -D - -X OPTIONS http://localhost:3000/somethingand see that the response comes from Svelte-Kit's server, not theoptionsmethod you just defined insomething.ts - Run
curl -D - -X OPTIONS http://localhost:3000/aboutand see that you get the same response
I'd like to give this a shot
I'm still figuring this out. Wonder if https://github.com/sveltejs/kit/discussions/5748 has any impact?
Would appreciate if someone could give some pointers on where to fix this.
Has there been any discussion around adding a generic “onRequest” function instead of splitting one function per HTTP method? That would also add compatibility with fetch based api frameworks like trpc and similar.
Any workaround to access the options request?
Would be nice to have this. I presume there is a workaround by using the svelte hooks
I managed to make OPTIONS work. (This option works for me locally & on Vercel, but most probably it would work elsewhere as well). This is needed if you're planning to invoke your function from a browser & solve CORS warning in SvelteKit.
In your hooks.server.ts use this:
import { corsHeaders } from '$lib/server/corsHeaders';
import type { Handle } from '@sveltejs/kit';
export const handle: Handle = async ({ event, resolve }) => {
if (event.request.method !== 'OPTIONS') {
const response = await resolve(event);
for (const [key, value] of Object.entries(corsHeaders)) {
response.headers.set(key, value);
}
return response;
}
return new Response('ok', { headers: corsHeaders });
};
I separated corsHeaders as server const in $lib/server/corsHeaders.ts
export const corsHeaders = {
'Access-Control-Allow-Credentials': 'true',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'OPTIONS,POST',
'Access-Control-Allow-Headers':
'authorization, x-client-info, apikey, X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version'
};
As a Bonus - you can modify the behaviour of your OPTIONS response to set Access-Control-Allow-Origin to only list of origin urls that you trust (e.g. localhost & your domains for staging, prod).
Additionally, you can also define which routes you allow from which origins.
Just console.log(event) to see which properties you might utilize 😉
p.s. just a junior developer here trying to help fellow devs
Just tried this for a Netlify deployment and it doesn't seem to work.
I managed to make OPTIONS work. (This option works for me locally & on Vercel, but most probably it would work elsewhere as well). This is needed if you're planning to invoke your function from a browser & solve CORS warning in SvelteKit.
In your
hooks.server.tsuse this:import { corsHeaders } from '$lib/server/corsHeaders'; import type { Handle } from '@sveltejs/kit'; export const handle: Handle = async ({ event, resolve }) => { if (event.request.method !== 'OPTIONS') { const response = await resolve(event); for (const [key, value] of Object.entries(corsHeaders)) { response.headers.set(key, value); } return response; } return new Response('ok', { headers: corsHeaders }); };I separated
corsHeadersas server const in$lib/server/corsHeaders.tsexport const corsHeaders = { 'Access-Control-Allow-Credentials': 'true', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'OPTIONS,POST', 'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version' };As a Bonus - you can modify the behaviour of your OPTIONS response to set
Access-Control-Allow-Originto only list of origin urls that you trust (e.g. localhost & your domains for staging, prod). Additionally, you can also define which routes you allow from which origins. Justconsole.log(event)to see which properties you might utilize 😉p.s. just a junior developer here trying to help fellow devs
if some got TypeError: immutable
here is a fix
import { corsHeaders } from '$lib/server/corsHeaders'
import type { Handle } from '@sveltejs/kit'
export const handle: Handle = async ({ event, resolve }) => {
if (event.request.method !== 'OPTIONS') {
const response = await resolve(event);
// clone headers before mutating them
// (https://github.com/sveltejs/kit/pull/10030/files#diff-7a5a1441a4765c525635c31466bc75c520fb481ec56d1606894270a73986ff86R58)
const headers = new Headers(response.headers);
for (const [key, value] of Object.entries(corsHeaders)) {
headers.set(key, value);
}
return response;
}
console.log("=> HOOK | handeled OPTIONS request")
return new Response('ok', { headers: corsHeaders });
};