skip to Main Content

I’ve been debugging this for several days, trying different deployment variations. My simple test full-stack app behaves as follows:

  1. it works fine when the backend server runs locally + frontend runs locally,
  2. it works fine when I run the backend locally with the frontend deployed on Netlify,
  3. when the backend deployed on render, and the frontend either run locally on from Netlify I am getting CORS error: has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. If an opaque response serves your needs, set the request’s mode to ‘no-cors’ to fetch the resource with CORS disabled. The request is 200, but blocked by CORS.

I don’t know what else I could do at this point. I use the cors package with some super basic configurations, yet this CORS error persists.

All env variables are triple-checked and properly added.

Below is my server.js file code:

const express = require("express");
const { initializeApp } = require("firebase/app");
const { getStorage, ref, getDownloadURL } = require("firebase/storage");
const cors = require("cors");
const dotenv = require("dotenv");

dotenv.config();

const app = express();

const allowedOrigins =
  process.env.NODE_ENV === "development"
    ? ["http://localhost:5173"]
    : [process.env.FRONTEND_URL];

app.use(
  cors({
    origin: (origin, callback) => {
      if (!origin || allowedOrigins.includes(origin)) {
        return callback(null, true);
      }

      callback(new Error("BE Error: Blocked by CORS policy"));
    },
  })
);

const firebaseConfig = {
  apiKey: process.env.FIREBASE_API_KEY,
  authDomain: process.env.FIREBASE_AUTH_DOMAIN,
  projectId: process.env.FIREBASE_PROJECT_ID,
  storageBucket: process.env.FIREBASE_STORAGE_BUCKET,
  messagingSenderId: process.env.FIREBASE_MESSAGING_SENDER_ID,
  appId: process.env.FIREBASE_APP_ID,
};

const firebaseApp = initializeApp(firebaseConfig);
const storage = getStorage(firebaseApp);

app.get("/api/image-url", async (req, res) => {
  const { path } = req.query;
  if (!path) {
    return res.status(400).send("Path is required");
  }

  try {
    const storageRef = ref(storage, path);

    const downloadUrl = await getDownloadURL(storageRef);

    return res.json({ url: downloadUrl });
  } catch (error) {
    console.error("Error fetching image URL:", error);
    return res.status(500).send("Failed to fetch image URL");
  }
});

const port = process.env.PORT || 3000;

app.listen(port, () => {
  console.log(`Server running on port: ${port}`);
});

I am fetching images stored on Firebase, FE fetch request calling the backend, and the backend is calling the Firebase.

React Vite FE portion:

const baseUrl =
  import.meta.env.MODE === "development"
    ? "http://localhost:3000"
    : import.meta.env.VITE_BACKEND_URL;

const getImageUrl = async ({ path }: { path: string }) => {
  try {
    const response = await fetch(`${baseUrl}/api/image-url?path=${path}`);
    if (!response.ok) {
      throw new Error("Failed to fetch image URL");
    }
    const data = await response.json();

    return data.url;
  } catch (e) {
    console.log("Error fetching images FE: error is", e);
    throw new Error("Error fetching images FE");
  }
};

export { getImageUrl };

fetch request header

error indicating cors issue

request headers

2

Answers


  1. Chosen as BEST ANSWER

    I made a mistake by incorrectly defining the script to run the server.js file in package.json. As a result, it was running an old build from the dist folder instead of running server.js file directly: INCORRECT:

     "scripts": {
        ...
        "start": "node dist/server.js"
      },
    

    CORRECT:

     "scripts": {
        ...
        "start": "node src/server.js"
      },
    

    Since I'm note using build, dist content is outdated and not used. Directly running server.js file solves the CORS issue!


  2. To fix the CORS issue in your Node/Express app deployed on Render:

    1. Check allowedOrigins: Ensure process.env.FRONTEND_URL is set correctly for production (e.g., https://your-netlify-site.netlify.app).

    2. Add Preflight Handling: Add this to handle OPTIONS requests:

      app.options('*', cors());
      
    3. Test with Wildcard: Temporarily allow all origins for debugging:

      app.use(cors({ origin: '*' }));
      
    4. Ensure Correct Fetch Settings: Use mode: 'cors' in your fetch request:

      fetch('https://your-backend-url.com/api/image-url', {
        method: 'GET',
        mode: 'cors',
        headers: { 'Content-Type': 'application/json' },
      });
      
    5. Check Render CORS Settings: Make sure Render is not overriding your CORS settings.

    6. Check Response Headers: Ensure Access-Control-Allow-Origin is set in the response headers.

    Test locally if the issue persists and check Render logs for errors.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search