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

Posted

技术标签:

【中文标题】使用默认 Next.js 开发服务器代理到后端【英文标题】:Proxy to backend with default Next.js dev server 【发布时间】:2020-07-10 12:03:06 【问题描述】:

以前,当我使用 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,
        )
    );
;

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

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

【问题讨论】:

【参考方案1】:

我的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`);
    );
);

package.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",
,

【讨论】:

NODE_ENV=development node -r esm server.js 如果使用require 那么const createProxyMiddleware = require('http-proxy-middleware'); 导入 createProxyMiddleware from 'http-proxy-middleware'; 另外,我做了node server.mjs 并删除了所有 ESM 自定义标记。节点 15 在 mjs 文件中使用 esm 可以很好地播放 :) 嗨,你这样做了吗?我做了 ti,但 build/nodemon 太长了【参考方案2】:

最终使用了类似于发布的内容。从这里使用的配置文件

https://github.com/zeit/next.js/tree/master/examples/with-custom-reverse-proxy

【讨论】:

【参考方案3】:

现在在配置中有一个官方特性:重写

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

next.config.js:

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

见Next.js Docs Rewrites

【讨论】:

当我想要 WebSocket 代理时,这个不起作用。握手失败。 @nemishzalavadiyaneel socket.io 对我来说也不管用重写...你能找到不涉及创建自定义服务器的解决方案吗? 我还是没有。我正在创建 const 对象并在那里存储硬编码的 URL。如果您找到任何解决方案,请分享。 我相信Rewrites 只是基本的代理设置。更多代理配置需要设置自定义服务器 如果有人在生产中的 nginx 配置中处理这个问题,这里只介绍如何进行配置选项开发。 nextjs.org/docs/api-reference/next.config.js/introduction【参考方案4】:

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

我使用了一个很好的旧常量:

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`)
  // ...

我更愿意代理请求并保持我的请求更干净,但我没有一天时间与这个搏斗。

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

【讨论】:

以上是关于使用默认 Next.js 开发服务器代理到后端的主要内容,如果未能解决你的问题,请参考以下文章

nginx学习之反向代理

使用Nodejs进行反向代理

Kubernetes出于什么考虑,放弃DNS轮询,而依赖代理模式将入站流量转发到后端呢?

Nginx 反向代理解决浏览器跨域问题

nginx http_realip_module 被高级安全防护设备代理后,获取用户端真实IP,并通过真实IP负载均衡转发到后端应用

nginx高可用