乐闻世界logo
搜索文章和话题

NextJS 如何使用代理服务器将请求代理到后端?

5 个月前提问
21 天前修改
浏览次数229

5个答案

1
2
3
4
5

在 Next.js 中,您可以使用两种主策略来代理请求到后端服务器:

1. 使用自定义服务器

您可以创建一个自定义的 Node.js 服务器,比如使用 Express.js,并在这个服务器中设置代理。这样,您可以在 Next.js 应用程序中捕获特定的 API 路径,并将它们转发到后端服务器。

以下是一个使用 Express 和 http-proxy-middleware 创建代理的示例:

首先,您需要安装 http-proxy-middleware

sh
npm install http-proxy-middleware

然后创建一个自定义的 Express 服务器,并使用 http-proxy-middleware 创建代理:

js
const express = require('express'); const next = require('next'); const { createProxyMiddleware } = require('http-proxy-middleware'); 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(); // 设置代理规则 server.use( '/api', // 代理路径 createProxyMiddleware({ target: 'http://backend-server.com', // 目标后端服务器 changeOrigin: true, pathRewrite: { '^/api': '', // 重写路径 }, }) ); // 其余的所有请求都通过Next.js处理 server.all('*', (req, res) => { return handle(req, res); }); server.listen(port, (err) => { if (err) throw err; console.log(`> Ready on http://localhost:${port}`); }); });

在这个示例中,所有指向 /api 的请求都会被代理到 http://backend-server.com,并且请求路径会被重写,移除 /api 前缀。

2. 使用 Next.js API Routes

Next.js 允许您在 pages/api 目录中创建 API 路由。您可以在这些路由中使用 Node.js 代码来处理 HTTP 请求,并且还可以在这里设置代理。

js
// pages/api/some-route.js import { createProxyMiddleware } from 'http-proxy-middleware'; // 创建代理中间件 export const config = { api: { bodyParser: false, externalResolver: true, }, }; const proxy = createProxyMiddleware({ target: 'http://backend-server.com', changeOrigin: true, pathRewrite: { '^/api': '', // 可以根据需要重写路径 }, }); export default (req, res) => { if (res.finished) return; // 使用代理中间件处理请求 return proxy(req, res, (result) => { if (result instanceof Error) { throw result; } throw new Error(`Request '${req.url}' is not proxied! We should never reach here!`); }); };

在这个例子中,pages/api/some-route.js 文件将处理所有指向 /api/some-route 的请求,并通过代理转发到后端。

注意:在生产环境中,通常建议直接在网络层级(例如使用 Nginx 或云服务提供商的功能)设置代理,以便于提高性能和可靠性。

使用这些方法,您可以在 Next.js 应用程序中设置代理服务器,并将请求代理到需要的后端服务器。

2024年6月29日 12:07 回复

现在配置中有一个官方功能:重写

除了正常的路径重写之外,它们还可以将请求代理到另一个网络服务器

next.config.js:

shell
module.exports = { async rewrites() { return [ { source: '/api/:path*', destination: 'http://localhost:8000/:path*' // Proxy to Backend } ] } }

请参阅Next.js 文档重写

2024年6月29日 12:07 回复

我的**server.js**设置,希望对你有帮助:

shell
import express from 'express'; import next from 'next'; import proxy from 'http-proxy-middleware'; 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(); server.use( '/api', proxy({ target: process.env.API_HOST, changeOrigin: true, }), ); server.all('*', (req, res) => handle(req, res)); server.listen(port, err => { if (err) throw err; console.log(`> Ready on http://localhost:${port}`); }); });

package.json:

shell
"scripts": { "dev": "NODE_ENV=development node -r esm server.js", "build": "NODE_ENV=production next build", "start": "NODE_ENV=production node -r esm server.js", },
2024年6月29日 12:07 回复

另一个带有包罗万象的路线的解决方案+ http-proxy-middleware

shell
// pages/api/proxy/[...slug].js import { createProxyMiddleware } from "http-proxy-middleware"; // @2.0.6 const proxy = createProxyMiddleware({ target: process.env.BACKEND_URL, secure: false, pathRewrite: { "^/api/proxy": "" }, // remove `/api/proxy` prefix }); export const config = { api: { externalResolver: true, bodyParser: false, }, } export default function handler(req, res) { proxy(req, res, (err) => { if (err) { throw err; } throw new Error( `Request '${req.url}' is not proxied! We should never reach here!` ); }); }

请参阅: https: //stackoverflow.com/a/72310680

2024年6月29日 12:07 回复

重写对我不起作用,使用 axios 也不起作用config.proxy

我诉诸了一个很好的老常数:

shell
const SERVER_URL = process.env.NODE_ENV === 'production' ? 'https://produrl.com : 'http://localhost:8000'; export async function getStaticProps() { const data = axios.get(`${SERVER_URL}/api/my-route`) // ... }

我更愿意代理请求并保持我的请求更干净,但我没有一天的时间来处理这个问题。

也许这个非常简单的设置会对其他人有所帮助。

2024年6月29日 12:07 回复

你的答案