Closed dBianchii closed 1 year ago
import { fetchRequestHandler } from "@trpc/server/adapters/fetch";
import { appRouter, createTRPCContext } from "@kdx/api";
const handler = async (req: Request) => {
const response = await fetchRequestHandler({
endpoint: "/api/trpc/edge",
router: edgeRouter,
req: req,
createContext: () => createTRPCContext({ req }),
onError: ({ error, path }) => {
console.log("Error in tRPC handler (edge)", path);
console.error(error);
console.error(error.cause ?? "No cause");
},
});
// configure cors
response.headers.set("access-control-allow-origin", "*");
response.headers.set("access-control-allow-headers", "*");
response.headers.set("access-control-allow-methods", "*");
response.headers.set("access-control-allow-credentials", "true");
return response;
};
export { handler as GET, handler as POST };
import { fetchRequestHandler } from "@trpc/server/adapters/fetch"; import { appRouter, createTRPCContext } from "@kdx/api"; const handler = async (req: Request) => { const response = await fetchRequestHandler({ endpoint: "/api/trpc/edge", router: edgeRouter, req: req, createContext: () => createTRPCContext({ req }), onError: ({ error, path }) => { console.log("Error in tRPC handler (edge)", path); console.error(error); console.error(error.cause ?? "No cause"); }, }); // configure cors response.headers.set("access-control-allow-origin", "*"); response.headers.set("access-control-allow-headers", "*"); response.headers.set("access-control-allow-methods", "*"); response.headers.set("access-control-allow-credentials", "true"); return response; }; export { handler as GET, handler as POST };
That was fast! Thank you <3
I still keep getting this error:
Access to fetch at 'http://localhost:3000/api/trpc/post.all?batch=1&input=%7B%220%22%3A%7B%22json%22%3Anull%2C%22meta%22%3A%7B%22values%22%3A%5B%22undefined%22%5D%7D%7D%7D' from origin 'http://localhost:3001' 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.
I tried to add
if (req.method === "OPTIONS") {
const responseHeaders = {
"Access-Control-Allow-Origin": "*", // Allow requests from any origin
"Access-Control-Allow-Methods": "*", // Allow all HTTP methods
"Access-Control-Allow-Headers": "*", // Allow all headers
"Access-Control-Allow-Credentials": "true", // Allow credentials
};
return new Response(null, {
headers: responseHeaders,
});
}
but no luck :/
UPDATE: I fixed it! I had to add
if (req.method === "OPTIONS") {
const responseHeaders = {
"Access-Control-Allow-Origin": "*", // Allow requests from any origin
"Access-Control-Allow-Methods": "*", // Allow all HTTP methods
"Access-Control-Allow-Headers": "*", // Allow all headers
"Access-Control-Allow-Credentials": "true", // Allow credentials
};
return new Response(null, {
headers: responseHeaders,
});
}
as I said, but then I also had to add to the exports:
export { handler as GET, handler as POST, handler as OPTIONS };
. Feel a little dumb for not noticing I had to export it as OPTIONS as well, if I am also doing if (req.method === "OPTIONS")
Here's my finished code:
import { fetchRequestHandler } from "@trpc/server/adapters/fetch";
import { appRouter, createTRPCContext } from "@kdx/api";
export const runtime = "nodejs";
// export API handler
const handler = async (req: Request) => {
if (req.method === "OPTIONS") {
const responseHeaders = {
"Access-Control-Allow-Origin": "*", // Allow requests from any origin
"Access-Control-Allow-Methods": "*", // Allow all HTTP methods
"Access-Control-Allow-Headers": "*", // Allow all headers
"Access-Control-Allow-Credentials": "true", // Allow credentials
};
return new Response(null, {
headers: responseHeaders,
status: 204,
});
}
const response = await fetchRequestHandler({
endpoint: "/api/trpc",
router: appRouter,
req,
createContext: () => createTRPCContext(),
});
// configure cors
response.headers.set("access-control-allow-origin", "*");
response.headers.set("access-control-allow-headers", "*");
response.headers.set("access-control-allow-methods", "*");
response.headers.set("access-control-allow-credentials", "true");
return response;
};
export { handler as GET, handler as POST, handler as OPTIONS };
Ah sorry, forgot about the OPTIONS request, here's what I did:
import { fetchRequestHandler } from "@trpc/server/adapters/fetch";
import { appRouter, createTRPCContext } from "@acme/api";
export const runtime = "nodejs";
function setCorsHeaders(res: Response) {
res.headers.set("Access-Control-Allow-Origin", "*");
res.headers.set("Access-Control-Request-Method", "*");
res.headers.set("Access-Control-Allow-Methods", "OPTIONS, GET, POST");
res.headers.set("Access-Control-Allow-Headers", "*");
}
export function OPTIONS() {
const response = new Response(null, {
status: 204,
});
setCorsHeaders(response);
return response;
}
async function handler(req: Request) {
const response = await fetchRequestHandler({
endpoint: "/api/trpc",
router: appRouter,
req,
createContext: () => createTRPCContext(),
});
// set CORS headers
setCorsHeaders(response);
return response;
}
export { handler as GET, handler as POST };
Ah sorry, forgot about the OPTIONS request, here's what I did:
import { fetchRequestHandler } from "@trpc/server/adapters/fetch"; import { appRouter, createTRPCContext } from "@acme/api"; export const runtime = "nodejs"; function setCorsHeaders(res: Response) { res.headers.set("Access-Control-Allow-Origin", "*"); res.headers.set("Access-Control-Request-Method", "*"); res.headers.set("Access-Control-Allow-Methods", "OPTIONS, GET, POST"); res.headers.set("Access-Control-Allow-Headers", "*"); } export function OPTIONS() { const response = new Response(null, { status: 204, }); setCorsHeaders(response); return response; } async function handler(req: Request) { const response = await fetchRequestHandler({ endpoint: "/api/trpc", router: appRouter, req, createContext: () => createTRPCContext(), }); // set CORS headers setCorsHeaders(response); return response; } export { handler as GET, handler as POST };
Also don't forget export { handler as GET, handler as POST, handler as OPTIONS };
Also don't forget export { handler as GET, handler as POST, handler as OPTIONS };
I am exporting a standalone function OPTIONS
instead. No need to run the entire tRPC handler for the OPTIONS request
Oh sorry, I didn't realize it was inside another function. This is better.
Hi,
It is a bad practice to allow access to your backend with a wildcard *
. It exposes you to attacks such as CSRF.
Your users' cookies could be sent (and accepted) from another website, potentially from a hacker.
You must specify which origin you allow specifically.
You can find more information in this article.
@juliusmarminge It would be better to remove the CORS headers by default. In this case, the Same-Origin will be applied. It means only the same origin will be able to call the backend.
For example:
It has recently changed, and now doesn't have NextRequest or NextResponse.