使用默认 Next.js 开发服务器代理到后端

ccl*_*oyd 11 javascript node.js reactjs next.js

之前,当我使用 create-react-app 制作应用程序时,我会有一个setupProxy.js文件来路由与此类似的 API 请求

const proxy = require('http-proxy-middleware');
module.exports = function(app) {
    app.use('/api',
        proxy({
            target: 'http://localhost:8000',
            changeOrigin: true,
        })
    );
};
Run Code Online (Sandbox Code Playgroud)

但这似乎不适用于 next.js。当我做同样的事情时,我会遇到各种错误。

谷歌搜索解决方案,很多人说使用某种自定义服务器。但是我将如何使用默认的 nextjs 开发服务器完成像上面这样的代理?(相当于我的 package.json 中的npm run devwhendevnext dev.

Bir*_*tab 25

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

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

next.config.js:

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

参见Next.js 文档重写

  • 当我想要 WebSocket 代理时,这个不起作用。它的握手失败了。 (4认同)

iam*_*ynq 6

我的server.js设置,希望它有帮助

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}`);
    });
});
Run Code Online (Sandbox Code Playgroud)

包.js

"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",
},
Run Code Online (Sandbox Code Playgroud)

  • 如果使用 `require` 则 `const { createProxyMiddleware } = require('http-proxy-middleware');` (2认同)

abe*_*ier 5

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

// 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!`
    );
  });
}
Run Code Online (Sandbox Code Playgroud)

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

  • 这可行,但您还需要将 API 路由配置选项设置为 `{"externalResolver": true, "bodyParser": false}`。它们分别告诉 Next.js 响应正在由代理中间件处理,并将原始请求正文传递给代理(否则非 GET 请求可能会失败。) (3认同)
  • 不,这些是 Next.js API 路由的选项,如下所述:https://nextjs.org/docs/api-routes/api-middlewares#custom-config (3认同)