在 Next.Js 的 useEffect 中进行网络调用时出现 CORS 错误
Posted
技术标签:
【中文标题】在 Next.Js 的 useEffect 中进行网络调用时出现 CORS 错误【英文标题】:CORS error when making network call in useEffect in Next.Js 【发布时间】:2021-08-27 13:13:04 【问题描述】:在 getStaticProps
中对 superhero.com
的 API 进行网络调用,但当我尝试在 useEffect
中进行相同操作时,它会引发 CORS 错误。
CORS 策略已阻止从源“http://localhost:3000”获取“https://superheroapi.com/api//1”的访问权限:没有“Access-Control-Allow-Origin”标头存在于请求的资源上。如果不透明的响应满足您的需求,请将请求的模式设置为“no-cors”以获取禁用 CORS 的资源。
我曾尝试使用 fetch 以及 axios 进行网络调用,但遇到了同样的错误。 Next.js 是否存在问题或限制?
编辑:尝试在useEffect
中使用 JSON 占位符 API,它正在工作。
【问题讨论】:
这能回答你的问题吗? How does Access-Control-Allow-Origin header work? 这是一个非常合理的错误,与 Next.js 无关,我没有想到会发生这种情况,一时冲动就贴在这里。答案中的@engineforce 非常简洁地解释了它。 【参考方案1】:CORS
当您尝试从另一个域的一个域访问资源时,会发生 CORS 错误。它只发生在浏览器中,是一项安全功能。
所以本质上,当您在localhost:3000
上从https://superheroapi.com/api/1
获取数据时,浏览器首先会询问superheroapi.com
,“嘿,这个域可以从你那里获取数据吗?”。 superheroapi.com
然后会说,“我只接受来自这些域的请求”。如果localhost:3000
不在该列表中,您将收到 CORS 错误。
https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
您可以通过Access-Control-Allow-Origin
标头更改superheroapi.com
接受的域。您可以手动完成,或者有一个方便的 npm 包可以在 Next.js 中为您处理。
修复 Next.js 中的 CORS
默认情况下,在 Next.js 中,CORS 标头仅限于同域流量。但是,您可以更改此设置。
Next.js 实际上在他们的文档中有一个关于向 api 路由添加 CORS 标头的指南。
https://nextjs.org/docs/api-routes/api-middlewares#connectexpress-middleware-support
不过,简而言之,首先安装 CORS 包。
npm i cors
# or
yarn add cors
# or
pnpm add cors
然后将其添加到 API 路由中。
import Cors from 'cors'
// Initializing the cors middleware
const cors = Cors(
methods: ['GET', 'HEAD'],
)
// Helper method to wait for a middleware to execute before continuing
// And to throw an error when an error happens in a middleware
function runMiddleware(req, res, fn)
return new Promise((resolve, reject) =>
fn(req, res, (result) =>
if (result instanceof Error)
return reject(result)
return resolve(result)
)
)
async function handler(req, res)
// Run the middleware
await runMiddleware(req, res, cors)
// Rest of the API logic
res.json( message: 'Hello Everyone!' )
export default handler
代码 sn-ps 取自 Next.js 文档。所有功劳都归功于 Next.js 的制作者。
【讨论】:
我试过了,当我从同一个 Next App 发出 POST 请求时,它通过了。由于方法中不允许 POST 请求,它不应该抛出错误吗?【参考方案2】:useEffect
中的代码在前端/浏览器中运行,因此必须遵守 CORS。 getStaticProps
在构建时运行,因此没有 CORS 限制。
如果 superheroapi.com API 在您的控制之下,您应该添加 CORS 响应标头来解决问题。否则需要创建反向代理,例如https://www.npmjs.com/package/cors-anywhere
【讨论】:
请查看编辑。解决 CORS 错误的解决方案是什么?【参考方案3】:您必须在经过验证的域上运行您的代码。 一些 api 给你 localhost 请求的 cors 错误。
简单的方法是:尝试定义一个本地域(在主机文件中将该域的本地 dns 更改为 127.0.0.1)并像这样编写一个 server.js 文件。 将“next.yourdomain.com”替换为您的域;)
const createServer, = require('http');
const parse, = require('url');
const next = require('next');
// const dev = process.env.NODE_ENV !== 'production';
const dev = false;
const app = next(dev, );
const handle = app.getRequestHandler();
const HOST = 'next.yourdomain.com';
const PORT = 8090;
app.prepare().then(() =>
createServer((req, res) =>
// Be sure to pass `true` as the second argument to `url.parse`.
// This tells it to parse the query portion of the URL.
const parsedUrl = parse(req.url, true);
handle(req, res, parsedUrl);
).listen(PORT, HOST, (err) =>
if (err) throw err;
console.log(`Starting Next.js at http://$HOST:$PORT`);
);
);
然后运行
next build && node server.js
您还必须在最终部署时丢弃此文件。
【讨论】:
以上是关于在 Next.Js 的 useEffect 中进行网络调用时出现 CORS 错误的主要内容,如果未能解决你的问题,请参考以下文章