CORS: preflight missing allow origin header

Hello!

I have a shopify store calling an API hosted here on render. However, any call sent from shopify to the API end up with a CORS error saying preflightmissingalloworiginheader. Digging into this, I’ve indeed noticed that the response coming from the API hosted on render does not contain Access-Control-Allow-* headers.

However, when calling the API hosted locally (same code), I can see the header in the response. I know that requests and responses to/from services hosted on render go through the render proxy and it seems that the proxy strips out the CORS header as you can see below.

curl -I -X POST https://clever-faces.onrender.com/api/projects

HTTP/2 500
date: Sat, 10 Aug 2024 07:14:01 GMT
content-type: text/html; charset=utf-8
cf-ray: 8b0e2fc6697ebb3c-CDG
cf-cache-status: DYNAMIC
vary: Accept-Encoding
content-security-policy: default-src ‘none’
rndr-id: 193738fd-7af0-463f
x-content-type-options: nosniff
x-powered-by: Express
x-render-origin-server: Render
server: cloudflare
alt-svc: h3=“:443”; ma=86400

curl -I -X POST http://127.0.0.1:3000/api/projects

HTTP/1.1 500 Internal Server Error
X-Powered-By: Express
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS,CONNECT,TRACE
Access-Control-Allow-Headers: Content-Type, Authorization, X-Content-Type-Options, Accept, X-Requested-With, Origin, Access-Control-Request-Method, Access-Control-Request-Headers
Access-Control-Allow-Credentials: true
Access-Control-Allow-Private-Network: true
Access-Control-Max-Age: 7200
Content-Security-Policy: default-src ‘none’
X-Content-Type-Options: nosniff
Content-Type: text/html; charset=utf-8
Content-Length: 152
Date: Sat, 10 Aug 2024 07:14:32 GMT
Connection: keep-alive
Keep-Alive: timeout=5

My API is a simple express js API:

const express = require('express');
const fs = require("fs");
const path = require("path");
const app = express();
const port = process.env.PORT || 3000; 

app.use((req: any, res: any, next: any) => {
  res.setHeader(
    "Access-Control-Allow-Origin",
    "*"
  );
  res.setHeader(
    "Access-Control-Allow-Methods",
    "GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS,CONNECT,TRACE"
  );
  res.setHeader(
    "Access-Control-Allow-Headers",
    "Content-Type, Authorization, X-Content-Type-Options, Accept, X-Requested-With, Origin, Access-Control-Request-Method, Access-Control-Request-Headers"
  );
  res.setHeader("Access-Control-Allow-Credentials", true);
  res.setHeader("Access-Control-Allow-Private-Network", true);
  res.setHeader("Access-Control-Max-Age", 7200);

  next();
});

app.options("*", (req: any, res: any) => {
  console.log("preflight");
  return res.status(204).send();
});

const routes = require('./routes');
app.use('/api', routes);

app.listen(port, '0.0.0.0', () => {
  console.log(`Running on ${port}`);
});

Could you please help me fix this problem ?

you will need to config CORS on your app:

const cors = require('cors');
...
app.use(cors({ origin: true, credentials: true });

npm -i cors
origin: true = all request, you can specify a string of your domain url or a array with string of allowed domains url.

Thanks for you answer rbarszcz. However, this is not the problem here. the cors library is simply a wrapper adding the headers as I’m manually doing in my code. I was actually using the code you provided until recently but needed more control and ended up adding the headers myself. The real problem is the headers are stripped out from the responses coming from render. As I mentioned, I see the headers in the responses coming from my local server. For now, I had to move my API on AWS unfortunately and I’m hopping for a solution soon to come back on render :slight_smile:

Hi there,

The provided code is not what is currently running on Render. This is why it doesn’t work as you expected.

Regards,

Keith
Render Support, UTC+10 :australia:

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.