Next.js本地axios调用外部API触发CORS跨域报错如何解决
问题原因
- CORS是浏览器独有的同源安全限制,仅作用于浏览器内发起的跨域请求。Postman、curl、纯服务端脚本发请求完全不受这个规则约束,这也是你在Postman里能正常拿到响应的核心原因。
- 你碰到的报错本质是BarcodeLookup的接口响应没有返回
Access-Control-Allow-Origin相关头,官方也没有提供跨域白名单配置入口,说明这个接口从设计上就不允许被浏览器端直接调用,和你把token放在请求头还是拼在URL参数里没有关系。 - 补充:纯Go后端直接发起请求不可能触发CORS报错,如果你用Go发请求也拿到类似错误,要么是你在Go代码里主动构造了带Origin头的浏览器模拟请求被接口拦截,要么是你把Go服务作为前端接口层,跨域实际发生在浏览器到你的Go服务这一段。
Next.js 适配方案
Next.js自带服务端运行能力,只要把第三方API请求放到服务端执行,就能完全绕开浏览器CORS限制,不需要对方接口做任何改动,两种常用实现如下:
方案1:Route Handler 转发(推荐,安全性更高)
如果用Next.js 13+的App Router,直接在app/api目录下新建服务端路由处理第三方请求,API key放在服务端环境变量(不要加NEXT_PUBLIC_前缀,不会泄露到前端):
// app/api/barcode/route.js import axios from "axios"; export async function GET(request) { const { searchParams } = new URL(request.url); const barcode = searchParams.get("barcode"); if (!barcode) { return Response.json({ error: "Barcode cannot be empty!" }, { status: 400 }); } try { const apiRes = await axios.get("https://api.barcodelookup.com/v3/products", { params: { upc: barcode, formatted: "y", token: process.env.BARCODELOOKUP_API_KEY } }); return Response.json(apiRes.data); } catch (err) { return Response.json({ error: "Request failed", msg: err.message }, { status: 500 }); } }
前端业务代码直接请求同域名下的本地接口即可,不会触发跨域:
export const getRecordInfoByBarcode = async (barcode) => { if (!barcode) throw new Error("Barcode cannot be empty!"); const res = await axios.get(`/api/barcode?barcode=${barcode}`); return res.data; }
方案2:配置代理重写(零业务代码改动)
不管是App Router还是老版本Pages Router,都可以在next.config.js里配置路径重写规则,由Next.js服务端自动代理请求到第三方接口:
// next.config.js /** @type {import('next').NextConfig} */ const nextConfig = { async rewrites() { return [ { source: "/api/barcode-proxy/:path*", destination: "https://api.barcodelookup.com/v3/:path*", }, ]; }, }; module.exports = nextConfig;
配置完成后重启开发服务,前端把请求地址改成代理路径即可:
const searchByBarcode = `/api/barcode-proxy/products?upc=${barcode}&formatted=y&token=${process.env.NEXT_PUBLIC_BARCODELOOKUP_API_KEY}`; const res = await axios.get(searchByBarcode);
注意:这个方案下如果直接把API key放在前端代码里,会有被他人盗用的风险,付费API优先选方案1把密钥存在服务端。
内容的提问来源于stack exchange,提问作者MrCujo
相关产品推荐
相关产品推荐

