CORS error on prod but not local
Unanswered
Polish posted this in #help-forum
PolishOP
Getting a CORS error when my app hits my NextJS API Route
"Access to fetch at 'https://mysite.com/api/store_session' from origin 'http://localhost:3001' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request."
The CORS code for mysite.com/api/store:
In next.config.mjs:
In /api/store/route.ts:
So on local when hitting my production server, I get CORS error. I'm trying to allow ANYONE to hit my production API. AFter adding the code above, I'm able to hit my LOCAL server with no issues (i.e. localhost:3001 can hit localhost:3000 no problem only after the above changes). But localhost:3001 (And any other site) can't hit the production API.
"Access to fetch at 'https://mysite.com/api/store_session' from origin 'http://localhost:3001' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request."
The CORS code for mysite.com/api/store:
In next.config.mjs:
const nextConfig = {
async headers() {
return [
{
source: '/api/store_session',
headers: [
{ key: 'Access-Control-Allow-Credentials', value: 'true' },
{ key: 'Access-Control-Allow-Origin', value: '*' },
{ key: 'Access-Control-Allow-Methods', value: 'OPTIONS' },
{
key: 'Access-Control-Allow-Headers',
value: 'X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version, Authorization'
},
],
},
];
},
};In /api/store/route.ts:
export async function OPTIONS() {
return new Response('', {
status: 200,
headers: {
'Access-Control-Allow-Credentials': 'true',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'POST, OPTIONS',
'Access-Control-Allow-Headers': 'X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version, Authorization'
}
});
}So on local when hitting my production server, I get CORS error. I'm trying to allow ANYONE to hit my production API. AFter adding the code above, I'm able to hit my LOCAL server with no issues (i.e. localhost:3001 can hit localhost:3000 no problem only after the above changes). But localhost:3001 (And any other site) can't hit the production API.
20 Replies
Komondor
you might need https://www.npmjs.com/package/nextjs-cors
PolishOP
Thanks @Komondor , will try that - but do you know why what I have rn doesn't work?
Your config should go in nextconfig.js not middleware.js
According to that blog post
PolishOP
Ah yes that was the guide I followed. Sorry I typo'd in the post, that code IS in my next.config.js. Updated the original post, thanks!
PolishOP
Ah and it looks like that nextjs-cors package is for Pages router only unfortunately. Appreciate the link though.
Komondor
are you exporting it from your next config?
module.exports = nextConfig
module.exports = nextConfig
How are you fetching the data?
PolishOP
@Komondor yep.
@Clown
in the user's browser this code runs:
And that call has the CORS problem. It works on localhost with the changes I described in the OP (though importantly does NOT work locally without those changes). And does not work on prod, giving the CORS error.
@Clown
in the user's browser this code runs:
fetch(`${BASE_URL}/api/store_session`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
events: this.buffer.data,
}),
});And that call has the CORS problem. It works on localhost with the changes I described in the OP (though importantly does NOT work locally without those changes). And does not work on prod, giving the CORS error.
Komondor
Your source api/store is different than the path that your client is requesting. I think you can wildcard it in the nextconfig
Brown bear
@Polish pls check your env
I am wondering how you did set base_url
I am wondering how you did set base_url
@Polish <@163858742767648768> yep.
<@678259999201427466>
in the user's browser this code runs:
typescript
fetch(`${BASE_URL}/api/store_session`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
events: this.buffer.data,
}),
});
And that call has the CORS problem. It works on localhost with the changes I described in the OP (though importantly does NOT work locally without those changes). And does not work on prod, giving the CORS error.
Brown bear
in this code,
if BASE_URL is not backend api, you are using nextjs api and then BASE_URL have to localhost:3001
else If you are using separate backend endpoint on mysite.com, you have to check backend site for cors error
if BASE_URL is not backend api, you are using nextjs api and then BASE_URL have to localhost:3001
else If you are using separate backend endpoint on mysite.com, you have to check backend site for cors error
So check BASE_URL variable using console.log
PolishOP
Oh no BASE_URL is actually a constant. mysite.com. I don't check any variables for it (the browser network tab shows mysite.com is what's being hit, which is correct)
@Komondor Your source api/store is different than the path that your client is requesting. I think you can wildcard it in the nextconfig
PolishOP
Woops, was another typo in the original (I updated the name). But at this point I'm ready to wildcard it just to get something working so will try that, thanks
PolishOP
Woops, was another typo in the original (I updated the name). But at this point I'm ready to wildcard it just to get something working so will try that, thanks.
Did the wildcard like this:
Error in browser is : "Access to fetch at 'https://mysite.com/api/store_session' from origin 'http://localhost:3001' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request."
Did the wildcard like this:
async headers() {
return [
{
source: '/:path*',
headers: [
{ key: 'Access-Control-Allow-Credentials', value: 'true' },
{ key: 'Access-Control-Allow-Origin', value: '*' },
{ key: 'Access-Control-Allow-Methods', value: 'POST, OPTIONS' },
{
key: 'Access-Control-Allow-Headers',
value: 'X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version, Authorization'
},
],
},
];
}, @Komondor even this didn't work, ugh. I must be missing something ehre.Error in browser is : "Access to fetch at 'https://mysite.com/api/store_session' from origin 'http://localhost:3001' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request."
PolishOP
In the terminal I ran
And this gave a 307 - is a redirect expected...?
curl -X OPTIONS https://mysite.com/api/store_session -IAnd this gave a 307 - is a redirect expected...?
HTTP/2 307
cache-control: public, max-age=0, must-revalidate
content-type: text/plain
date: Fri, 26 Apr 2024 21:18:01 GMT
location: https://www.mysite.com/api/store_session
server: Vercel
strict-transport-security: max-age=63072000
x-vercel-id: sfo1::hkqhr-1714166281689-e0819b376eacPolishOP
OMG, I got it. The problem was my client was hitting https://mysite.com instead of https://www.mysite.com
And vercel was recirecting mysite.com to www.mysite.com.
And vercel was recirecting mysite.com to www.mysite.com.
Thanks all for looking, really appreciate your time.