No 'Access-Control-Allow-Origin' header

My deployment works fine now, so I would like to share how I managed to solve these issues.

To be clarified, this is my solutions based on my assumptions that may not works perfectly in other case. If there are some context incorrect, feel free to point out.

Issues that I met:

  1. No ‘Access-Control-Allow-Origin’ header is present on the requested resource.
  2. Preflight request warning
  3. Timed out after waiting for internal health check to return a successful response code

My solution for “No ‘Access-Control-Allow-Origin’ header” :

const express = require("express");
const app = express();
// Set middleware of CORS 
app.use((req, res, next) => {
  res.setHeader(
    "Access-Control-Allow-Origin",
    "https://your-frontend.com"
  );
  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);
  //  Firefox caps this at 24 hours (86400 seconds). Chromium (starting in v76) caps at 2 hours (7200 seconds). The default value is 5 seconds.
  res.setHeader("Access-Control-Max-Age", 7200);

  next();
});
To fix preflight request warning

Introduction about preflight request

I tried to connect my static site on render to my local server for debugging my request on my browser developer tool. The following code works fine on Firefox, but Chrome seems to send preflight request twice with one fail and one succeed which turns out to be a bug on chrome itself.

// Set preflight
app.options("*", (req, res) => {
  console.log("preflight");
  if (
    req.headers.origin === "https://badmintown.onrender.com" &&
    allowMethods.includes(req.headers["access-control-request-method"]) &&
    allowHeaders.includes(req.headers["access-control-request-headers"])
  ) {
    console.log("pass");
    return res.status(204).send();
  } else {
    console.log("fail");
 
To solve health check timeout

According to health check:

What you return on your health check path is up to you, but we recommend running quick sanity checks (like a simple database query) and returning an “OK” 200 response or an empty 204 response if the app is healthy.

To make the health check process faster, I wrote path for it:

app.get("/healthz", (req, res) => {
  console.log("health check is processed");
  return res.status(204).send();
});
Why I set CORS manually

At the beginning, I used node.js package CORS to configure CORS as below:

const express = require("express");
const app = express();
const cors = require("cors");
const corsOptions = {
  origin:"https://your-frontend.com",
  methods: "GET,HEAD,PUT,PATCH,POST,DELETE",};
app.use(cors(corsOptions));

However, this did not work and the error kept showing as:

Access to XMLHttpRequest has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

Therefore, I assumed that this package may not work successfully during deployment, so I tried to code my CORS configuration manually.