Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Method Options - HTTP #5193

Closed
RogerioBorba opened this issue Jun 10, 2022 · 9 comments · Fixed by #8731
Closed

Method Options - HTTP #5193

RogerioBorba opened this issue Jun 10, 2022 · 9 comments · Fixed by #8731
Labels
feature / enhancement New feature or request help wanted PRs welcomed. The implementation details are unlikely to cause debate low hanging fruit p3-edge-case SvelteKit cannot be used in an uncommon way
Milestone

Comments

@RogerioBorba
Copy link

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

@rmunn
Copy link
Contributor

rmunn commented Jun 16, 2022

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.ts containing 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/something to verify that the GET method works (and prints "get")
  • Run curl -D - -X OPTIONS http://localhost:3000/something and see that the response comes from Svelte-Kit's server, not the options method you just defined in something.ts
  • Run curl -D - -X OPTIONS http://localhost:3000/about and see that you get the same response

@rmunn rmunn added feature / enhancement New feature or request p3-edge-case SvelteKit cannot be used in an uncommon way labels Jun 16, 2022
@Rich-Harris Rich-Harris added help wanted PRs welcomed. The implementation details are unlikely to cause debate low hanging fruit labels Jul 15, 2022
@Rich-Harris Rich-Harris added this to the whenever milestone Jul 15, 2022
@tsriram
Copy link

tsriram commented Jul 21, 2022

I'd like to give this a shot

@tsriram
Copy link

tsriram commented Jul 29, 2022

I'm still figuring this out. Wonder if #5748 has any impact?

Would appreciate if someone could give some pointers on where to fix this.

amunim added a commit to amunim/Svelte-kit that referenced this issue Aug 18, 2022
amunim added a commit to amunim/Svelte-kit that referenced this issue Aug 18, 2022
Fixed sveltejs#5193

Formatted using `pnpm format`
@cleaton
Copy link

cleaton commented Oct 4, 2022

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.

@MohamedElshazly
Copy link

Any workaround to access the options request?

@AlbertMarashi
Copy link

Would be nice to have this. I presume there is a workaround by using the svelte hooks

@dj-nuo
Copy link

dj-nuo commented Jan 15, 2023

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

@TrystonPerry
Copy link

Just tried this for a Netlify deployment and it doesn't seem to work.

@SaicharanKandukuri
Copy link

SaicharanKandukuri commented Nov 14, 2023

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

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 });
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature / enhancement New feature or request help wanted PRs welcomed. The implementation details are unlikely to cause debate low hanging fruit p3-edge-case SvelteKit cannot be used in an uncommon way
Projects
None yet
Development

Successfully merging a pull request may close this issue.