Skip to content
Advertisement

Next.js and Express.js give CORS error, API queries only work at build time

I have a project where I use Next.js on the front-end and Express.js on the back.

Front-end side The ‘pages’ file contains ‘index.js’. In it, I am sending the following request.

    import Home from "./home/home";
import axios from "axios";

import { useState } from "react";
export default function Index({ data }) {
  const [products, setProducts] = useState(data);
  const [start, setStart] = useState(1);

  const getMoreProducts = async () => {
    setStart(start + 1);
    const { newProducts } = await axios.get(
      `${process.env.NEXT_PUBLIC_BACK_END}/test`
    );

    setProducts([...products, ...newProducts]);
  };

  return (
    <div>
      <Home data={products} />
      <button onClick={getMoreProducts}> Load more {start}</button>
    </div>
  );
}

export async function getServerSideProps(context) {
  // Fetch data from external API
  const { data } = await axios.get(
    `${process.env.NEXT_PUBLIC_BACK_END}/productlist/pagination`,
    {
      params: {
        page: 1,
        limit: 5,
      },
    }
  );

  return {
    props: {
      data: data || {},
    },
  };

  // Pass data to the page via props
}

Back-end side

const express = require("express");
var cors = require('cors')




const app = express();
require("dotenv").config();
const mongoose = require("mongoose");

mongoose.connect(
  "*********",
  { useNewUrlParser: true }
);
const db = mongoose.connection;

db.on("error", (err) => console.error(err));
db.once("open", () => console.log("Connected to Database "));

app.use(express.json());
const productlistRouter = require("./routes/productlist");
const test = require("./routes/test");

app.use("/productlist", productlistRouter);
app.use("/test", test);
app.use(cors())
app.listen(3000, () => console.log("Server is running"));

And here is my Route code :

const express = require("express");
const router = express.Router();
const Product = require("../models/product");
const cors = require("cors");

const corsOptions = {
  headers: [
    { key: "Access-Control-Allow-Credentials", value: "true" },
    { key: "Access-Control-Allow-Origin", value: "*" },
    // ...
  ],
  origin: "*",
  optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204
};
router.get("/showall", async (req, res) => {
  try {
    const product = await Product.find();
    res.json(product);
  } catch (err) {
    res.status(500).json({ message: err.message });
  }
});

router.get("/pagination", cors(corsOptions), async (req, res) => {
  const page = req.query.page;
  const limit = req.query.limit;
  const startIndex = (page - 1) * limit;
  const endIndex = page * limit;
  const products = await Product.find();
  const result = products.slice(startIndex, endIndex);
  res.json(result);
});

So, When the page is first built with Next.js, the api works, but when I click the ‘Load more’ button, it gives a CORS error. When I use the same query with ‘postman’ and other tools, it does not give any error. On the Next.js side, it works when I send a query to another 3rd party API., but it doesn’t work when I send it to my own back-end. And no matter what page or component I do this in, only the APIs that are created at the build time are working.

What could be the reason for this? and how can i solve it? I’ve read and searched a few articles about cors, but I still haven’t found a solution for days.

Advertisement

Answer

CORS should be placed on top level as javascript is executed one by one line. Place app.use(cors()) just above the line of app.use("/productlist", productlistRouter);

User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement