Search code examples
node.jstypescriptcorsserverlessvercel

Node serveless Cors on Vercel


Im having some issues with enabling cors for a node function running on vercel.

I have the following in a file api/index.ts

import type {VercelRequest, VercelResponse} from '@vercel/node';

export default (req: VercelRequest, res: VercelResponse) => {
  return res.status(200).json({hello: 'world'});
};

and this is the vercel.json in the root of the project.

{
    "headers": [
      {
        "source": "/api/(.*)",
        "headers": [
          { "key": "Access-Control-Allow-Credentials", "value": "true" },
          { "key": "Access-Control-Allow-Origin", "value": "*" },
          { "key": "Access-Control-Allow-Methods", "value": "GET,OPTIONS,PATCH,DELETE,POST,PUT" },
          { "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" }
        ]
      }
    ]
  }

When deployed to vercel and fetching from a localhost

fetch('https://myapp.vercel.app/api').then(res => res.json()).then(data => {
  document.querySelector('h1').innerHTML = `data`;
});

I get the cors error stating that the Access-Control-Allow-Origin header is missing

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://myapp.vercel.app/api. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing). Status code: 200.

Is there addition setup needed for the headers to be sent?

I have tried various suggestions found from googling, most of the cors issues raised are for Next ( which I am not using ) the only dep is on the Vercel/node package ( for types ).


Solution

  • You've specified a CORS policy for endpoints that match pattern /api/(.*),

    "source": "/api/(.*)",
    

    but you're requesting /api, which does not match that pattern. Either requesting /api/ instead of /api or modifying your pattern accordingly should solve the issue.

    Besides, be aware that the wildcard (*) isn't compatible with credentialed requests. Because you don't seem to need requests with credentials, you should be able to safely drop the following line from your CORS config anyway:

    { "key": "Access-Control-Allow-Credentials", "value": "true" },