CORS - NextJS - API Routes: cors error when trying to fetch server side endpoint (pages/api) from client side XHR

Another CORS topic, it’s impresive how many are…

The context:

const { i18n } = require('./next-i18next.config')

const configuration = {
  pageExtensions: ['page.js', 'route.js'],
  webpack: (config, { isServer }) => {
    config.module = {
      ...config.module,
      exprContextCritical: false,
    };
    if (!isServer) {
      config.resolve.fallback = { 
        buffer: false,
        fs: false,
        process: false,
        util: false,
        assert: false,
      };
    }
    config.resolve.symlinks = false
    return config;
  },  
  serverRuntimeConfig: {
      PROJECT_ROOT: __dirname
  },
  distDir: 'build',  
  basePath: process.env.NEXT_PUBLIC__BASE_PATH,
  i18n: i18n,
  experimental: {
    appDir: false,
  },  
  reactStrictMode: true,  
}

module.exports = configuration

The problem:

  • when I try to fetch and API endpoint ( /api/post > src/pages/api/post.route.js ) from the client ( / > src/pages/index.page.js ) gets a CORS error

[Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at...]

on Localhost:
when I test this on localhost, the response header returns

"access-control-allow-origin : *"

but it’s missing when I test it on netlify

What I’ve tried:

  • _headers file, inside the root directory and then inside the root/public
/*
  Access-Control-Allow-Origin: *
  • netlify.toml
[[headers]]
  for = "/*"
  [headers.values]
    Access-Control-Allow-Origin = "*"
  • setting the header in the route /root/pages/api/
import { createRouter } from "next-connect";
import cors from "cors";

const router = createRouter();
router
.use(cors())
.get( async(req, res) => {
  const resp = await getData(req);
  return res.json(resp);
})

export default router.handler({
  onError(err, req, res) {
    res.status(500).json({
      error: (err).message,
    });
  },
})

async function getData(req) {
  return { data: "some data"}
}

and with this (netlify instant answers)

export default async (req, ctx) => {
  let res = ctx.json( await getData(req) )
  res.headers.append('Allow-Access-Control-Origin', '*')
  return res
}

async function getData(req) {
  return { data: "some data"}
}


// this produces an error: Error [ERR_STREAM_WRITE_AFTER_END]: write after end

Logs

If the request was called from the SSR all the logs are shown on the Function Next.js SSR handler System but when are called from the ClientSide they don’t even log here

Questions

  • Are the api/endpoints accesible to the internet?

Yes, they are available

https://jmarroyave-dev.netlify.app/api/blog
https://jmarroyave-dev.netlify.app/api/post?id=03-4-uncompleted-tasks

  • Where are those requests logged?

Thanks for the help.

JM

None (or at least not most) of those have been an issue from Netlify’s end :slight_smile:

Users need to understand, CORS comes from the destination server that you’re connecting to, not from the server that’s hosting your site. Unfortunately, they see the error in the console from an app that’s deployed on Netlify and assume it’s a Netlify issue.

Same is the case with you… the error comes from the destination server:

I don’t see this issue on your latest deploy though, so maybe you’ve already fixed it.

Hi hrishikesh, thanks for your response

I think you don’t really get it. It’s not about if they occurred on Netlify’s end or doesn’t it’s about the amount of Netlify’s users that makes a report because they don’t find an answer.

No, that one it’s still happening. I had to change the fetch logic to make it work.

The problem that I was facing was when I want to fetch something from a localhost API, somehow, the CORS headers were missing and despite the console.log on the server side, I couldn’t find any record about the request. Could you help me in figuring out how to debug this

Sorry if I sound defensive, but since we strive to answer literally all technical support questions, I kinda feel bad when someone says “there are so many reports because users don’t find an answer”. If there are many threads and if some are unanswered, there could be multiple reasons for that:

  1. Most people don’t bother to search and create duplicate threads.
  2. We ask them to try something and they never reply.
  3. We can’t help users with some custom configuration on their own end which has nothing to do with Netlify.

Regarding your issue though, I’m sorry I don’t understand this part:

Are you trying to connect to localhost from Netlify? That’s not possible. Based on my above screenshot, you seemed to be connecting to render.com, not localhost.

Could you try to phrase your question a bit differently maybe? For example, try answering this questions:

  1. Where are you getting the CORS error exactly? Is it on the client-side, or in server-side (doesn’t seem likely)?
  2. Where are you connecting, or where the API you’re trying to connect to lives? Can you control that server?

A simpler solution is to use Netlify Rewrites to trick browsers into thinking this is a same-origin request.