next.js 下一个CORS问题

rggaifut  于 2022-12-18  发布在  其他
关注(0)|答案(9)|浏览(320)

我有一个托管在Vercel www.example.com上的Next.js应用程序,它需要与托管在另一台服务器api.example.com上的后端.NET核心Web API通信。.NET核心Web API已配置为允许CORS,但我的Next.js一直抱怨在使用AXIOS获取数据时无法显示数据,因为响应缺少allow-cors标头:
CORS策略已阻止从源“http://www.example.com”访问位于“api.example.comhttps:www.example.com”的XMLHttpRequest:对印前检查请求的响应未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”标头
当我使用npm run dev在本地运行它时,它工作正常,但是当我构建它然后运行npm run start时,它就不工作了
有人知道如何解决生产中的cors问题吗?

kgsdhlau

kgsdhlau1#

我找到了一个解决方案here
基本上,我只需要在根目录中添加一个next.config.js文件,并添加以下内容:

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

bq9c1y662#

如果你想在nextjs中使用cors库,我为它创建了一个库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!' });
}
wqnecbli

wqnecbli3#

这是服务器不接受OPTIONS请求的问题,因为路由被声明为GET::something或POST::一些东西,所以预检无法通过,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();
});
wnrlj8wa

wnrlj8wa4#

我也有类似的问题,我是从这个页面打电话:

页/页1.js

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

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

页/页1.js

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

页面/API/获取页面1数据. 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)
  }

envsm3lx

envsm3lx5#

做一个额外的检查,如果你的基本网址是正确的,这是我的问题

xmq68pz9

xmq68pz96#

在我的例子中,由于一个激进的HTTP方法过滤器,预检请求失败了。
请确保指定

// Preflight Check:
  if (req.method == "OPTIONS") {
    res.setHeader("Allow", "POST");
    return res.status(202).json({});
  }

  // Allow only POST Methods 
  if (req.method !== "POST") {
    res.setHeader("Allow", "POST");
    return res.status(405).json({ error: `Method ${req.method} Not Allowed` });
  }

您可以使用https://vercel.com/support/articles/how-to-enable-cors#enabling-cors-in-a-next.js-app允许所有方法,但要确保每个端点都为OPTIONS HTTP方法返回2XX状态代码。

xmjla07d

xmjla07d7#

请确保它是CORS,而不是其他东西。例如,在我的情况下,我得到了400响应。请查看该请求的Response选项卡以获取信息。

r6l8ljro

r6l8ljro8#

在谷歌上搜索了几个小时后,我在next上找到了解决方案--docs本身!!!
请参阅github上的以下存储库

使用CORS的API路径示例

https://github.com/vercel/next.js/tree/canary/examples/api-routes-cors

g52tjvyc

g52tjvyc9#

我有Next.js应用程序,其中包含graphql和Apollo客户端设置(Apollo版本:3.5.10)。为了在任何组件内进行查询,您必须使用Apollo客户端提供的“client”变量。您需要在项目根目录中有apollo-client.js文件,以便Apollo客户端可以在任何组件内使用它进行查询。在任何组件内,当您尝试进行以下查询时:client.query(...),使用apollo-client文件的这些设置会引发“cors”错误。但是,您可以通过在apollo-client文件中添加头属性来修复此错误。
这是旧设置:

阿波罗客户端.js(旧版本)

import { ApolloClient, InMemoryCache } from '@apollo/client';

const client = new ApolloClient({
  uri: 'http://localhost:4000/graphql',
  cache: new InMemoryCache(),
});

export default client;

这是新设置:

apollo-client.js(新版本)

import { ApolloClient, InMemoryCache } from '@apollo/client';

const client = new ApolloClient({
  uri: 'http://localhost:4000/graphql',
  cache: new InMemoryCache(),
  headers: {
    fetchOptions: {
      mode: 'no-cors',
    },
  },
});

export default client;

这样,在任何组件内部执行查询时,都不会出现任何“cors”错误。

相关问题