banner
rabithua

rabithua

twitter
github

NEXT Two Solutions to Cross-Domain Issues

Next is a react framework that allows for full-stack integration and is a good choice for projects. This article documents the process of handling cross-origin resource sharing (CORS) issues during the development process a few days ago. [Recommended Solution 2, Solution 2 is also simpler, but requires a little bit of basic knowledge of Node.js]

Before starting, please make sure that the cross-origin interface you have prepared can be called normally. If there are any errors during the practice process, please check if the interface is normal first, and then check if the local cross-origin configuration is incorrect. Avoid being busy for half a day and finding out that the original interface has problems :@(装大款)

Solution 1: Create a server.js file in the project directory and use the package.json scripts option to implement cross-origin requests in the development environment.#

Implementation>>>#

  • Create a server.js file in the project root directory, which is the same level as the package.json file. The code of the file is as follows:
// server.js
const express = require('express')
const next = require('next')
const { createProxyMiddleware } = require('http-proxy-middleware')

// Specific configuration for cross-origin
const devProxy = {
    '/email': {
        target: 'https://api.postmarkapp.com/', 
        changeOrigin: true
    }
}

// The following content remains unchanged. If you don't understand, please do not modify it.
const port = parseInt(process.env.PORT, 10) || 3000
const dev = process.env.NODE_ENV !== 'production'
const app = next({
    dev
})
const handle = app.getRequestHandler()

app.prepare()
    .then(() => {
        const server = express()
        if (dev && devProxy) {
            Object.keys(devProxy).forEach(function (context) {
                // http-proxy-middleware new usage 2
                server.use(createProxyMiddleware(context, devProxy[context]))
            })
        }

        server.all('*', (req, res) => {
            handle(req, res)
        })

        server.listen(port, err => {
            if (err) {
                throw err
            }
            console.log(`> Ready on http://localhost:${port}`)
        })
    })
    .catch(err => {
        console.log('An error occurred, unable to start the server')
        console.log(err)
    })

  • The example calls an interface for sending emails using postmark, and the original interface address is https://api.postmarkapp.com/email, using a get request.
  • According to the above code, the actual request method is as follows:
import axios from "axios";

export const waitlistEmailSend = (data: any) => {
  return new Promise((resolve, reject) => {
    try {
      axios({
        method: "post",
        url: "/email",
        data,
        headers: {
          Accept: "application/json",
          "X-Postmark-Server-Token": "***TOKEN***",
          "Content-Type": "application/json",
        },
      }).then((res: any) => {
        // console.log(res.code);
        if (res.status == 200) {
          resolve(res);
        } else {
          reject(res);
        }
      });
    } catch (error) {
      console.error(error);
      reject(error);
    }
  });
};
  • Configure cross-origin startup in package.json: "dev:node-middleware": "node server.js", and then start the project by running npm run dev:node-middleware and call the encapsulated request.
{
...
"scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
    "dev:node-middleware": "node server.js"
  }
...
}
  • It can be seen that the actual request to the local /email interface is forwarded to https://api.postmarkapp.com/email by the middleware, and the cross-origin is successful. The network request on the f12 page shows that it is a request to localhost.

Solution 2: Encapsulate the cross-origin interface in the backend API provided by Next, and implement cross-origin in the project by calling the encapsulated API in the frontend.#

Generally, in a newly created Next project, there will be a pages/api/hello.ts file, which is the backend API provided by Next. Requesting the cross-origin interface here will not trigger a cross-origin error. This is actually easy to understand. The backend is like a local environment, and all your requests are made directly without having its own domain name like the frontend. Therefore, there is no cross-origin issue.
If you understand Node.js, you can skip the tutorial. Everything is the same as using your Node.js backend.

Implementation>>>#

  • Create a Next backend API in pages/api/waitlistemail.ts. The example code is as follows:
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import axios from "axios";
import type { NextApiRequest, NextApiResponse } from "next";

type Data = {
  code: number;
  data: any;
  errMsg: string;
};

export default function handler(
  req: NextApiRequest,
  res: NextApiResponse<Data>
) {
  console.log(req.body);
  if (req.body.To) {
    console.log("send");
    try {
      axios({
        method: "post",
        url: "https://api.postmarkapp.com/email",
        data: req.body,
        headers: {
          Accept: "application/json",
          "X-Postmark-Server-Token": "***TOKEN***",
          "Content-Type": "application/json",
        },
      }).then((r: any) => {
        console.log(r.status);
        if (r.status == 200) {
          res
            .status(200)
            .json({ code: 0, data: "", errMsg: "Email send success!" });
        } else {
          res
            .status(200)
            .json({ code: 1, data: "", errMsg: "Email send fail!" });
        }
      });
    } catch (error) {
      res
        .status(200)
        .json({ code: 1, data: "", errMsg: "Email send success!" });
    }
  } else {
    res.status(200).json({ code: 1, data: "", errMsg: "Email send fail!" });
  }
}

  • Call the interface in Next frontend, the code is as follows:
import axios from "axios";

export const waitlistEmailSend = (data: any) => {
  return new Promise((resolve, reject) => {
    try {
      axios({
        method: "post",
        url: "/api/waitlistemail",
        data,
      }).then((res: any) => {
        // console.log(res);
        if (res.data.code == 0) {
          resolve(res);
        } else {
          reject(res);
        }
      });
    } catch (error) {
      reject(error);
    }
  });
};

  • Call the interface, the request is successful, and it is still a request to localhost.

Related links: Nextjs axios

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.