NextJs CORS 问题

Yoo*_*ope 9 cors reactjs next.js

我在www.example.com 的Vercel 上托管了一个 Next.js 应用程序,它需要与托管在 api.example.com 的不同服务器上的后端 .NET Core Web API 进行通信。.NET 核心 Web api 已配置为允许 CORS,但我的 Next.js 一直抱怨当我使用 AXIOS 获取数据时无法显示数据,因为响应缺少 allow-cors 标头:

CORS 政策已阻止从源“http://www.example.com”访问“https://api.example.com”上的 XMLHttpRequest:对预检请求的响应未通过访问控制检查:否“访问” -Control-Allow-Origin' 标头存在于请求的资源上

当我使用 本地运行它时它工作正常npm run dev,但是当我构建它然后运行时它不起作用npm run start

有谁知道如何解决生产中的 cors 问题?

小智 24

如果你想使用cors中的库nextjs,我为其创建了一个库nextjs-cors

https://www.npmjs.com/nextjs-cors

https://github.com/yonycalsin/nextjs-cors

页面/api/whoami.{ts,js}

import NextCors from 'nextjs-cors';

async function handler(req, res) {
   // Run the cors middleware
   // nextjs-cors uses the cors package, so we invite you to check the documentation https://github.com/expressjs/cors
   await NextCors(req, res, {
      // Options
      methods: ['GET', 'HEAD', 'PUT', 'PATCH', 'POST', 'DELETE'],
      origin: '*',
      optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 204
   });

   // Rest of the API logic
   res.json({ message: 'Hello NextJs Cors!' });
}
Run Code Online (Sandbox Code Playgroud)


Yoo*_*ope 15

我在这里找到了解决方案:

基本上,我只需要在根目录中添加一个 next.config.js 文件并添加以下内容:

// next.config.js
module.exports = {
    async rewrites() {
        return [
          {
            source: '/api/:path*',
            destination: 'https://api.example.com/:path*',
          },
        ]
      },
  };
Run Code Online (Sandbox Code Playgroud)

  • 它不适用于 Vercel。有什么线索吗? (4认同)
  • 我得到了答案并且它有效。但为什么 NextJS 会发生这种情况呢? (2认同)
  • 您还需要将相同的配置添加到 vercel.json:https://vercel.com/support/articles/how-to-enable-cors#enabling-cors-using-vercel.json (2认同)

chi*_*aos 15

我遇到了类似的问题,我是从这个页面拨打电话的:

页面/page1.js

  export default async function page1() {
       const data = await axios.post('https://www.dominio.com/xxx' , {param: 1}, headers)
}
Run Code Online (Sandbox Code Playgroud)

但解决方案是对“pages/api”目录中的本地 API 文件进行 axios 调用,该本地 API 文件将处理对外部 Web 服务器的请求。这避免了 CORS 问题。

页面/page1.js

export default async function page1() {
        const data = await axios.post('/api/get_page1_data', {param: 1} )
}
Run Code Online (Sandbox Code Playgroud)

页面/api/get_page1_data.js

export default async function handler(req, res) {
try{
   const data = await axios.post('https://www.dominio.com/xxx' , {param: req.body.param}, headers)
    res.status(200).json(data)
 } catch (error) {
    console.error(error)
    return res.status(error.status || 500).end(error.message)
  }
Run Code Online (Sandbox Code Playgroud)

  • 这意味着您正在提出两个请求,而不是一个。一个用于下一个服务器,另一个用于 API,这是没有意义的。 (2认同)

inz*_*nzo 15

这是服务器不接受 OPTIONS 请求的问题,因为路由被声明为 GET::something 或 POST::something,所以预检无法通过并且 POST 请求被拒绝,希望这将帮助其他人避免几个小时谷歌搜索,所以在我的例子中(Node.js + Express.js)我必须将其添加到我的 server.js 中

  app.use((req, res, next) => {
    res.header("Access-Control-Allow-Origin", "*");
    res.header(
      "Access-Control-Allow-Headers",
      "Origin, X-Requested-With, Content-Type, Accept, Authorization"
    );
  if (req.method == "OPTIONS") {
    res.header("Access-Control-Allow-Methods", "PUT, POST, PATCH, DELETE, GET");
    return res.status(200).json({});
  }

  next();
});
Run Code Online (Sandbox Code Playgroud)


小智 5

额外检查一下您的基本网址是否正确,这是我的问题