如何为 Next.js API 请求进行 HTTP 代理

17 http-proxy node.js express http-proxy-middleware next.js

我在网上尝试了很多方法,但到目前为止没有任何效果。

第一次尝试 (src/pages/api/proxy/[...slug].js):

import { createProxyMiddleware } from 'http-proxy-middleware';

// Create proxy instance outside of request handler function to avoid unnecessary re-creation
const apiProxy = createProxyMiddleware({
    target: 'http://localhost:5000',
    changeOrigin: true,
    pathRewrite: { [`^/api/proxy`]: '' },
    secure: false,
});

export default function (req, res) {
    apiProxy(req, res, (result) => {
        if (result instanceof Error) {
            throw result;
        }

        throw new Error(`Request '${req.url}' is not proxied! We should never reach here!`);
    });
};
Run Code Online (Sandbox Code Playgroud)

给我这样的错误:

TypeError: Object(...) is not a function
    at Module../pages/api/[...slug].js (/home/user/app/client/.next/server/pages/api/[...slug].js:109:101)
    at __webpack_require__ (/home/user/app/client/.next/server/pages/api/[...slug].js:23:31)
    at /home/user/app/client/.next/server/pages/api/[...slug].js:91:18
    at Object.<anonymous> (/home/user/app/client/.next/server/pages/api/[...slug].js:94:10)
    at Module._compile (node:internal/modules/cjs/loader:1092:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1121:10)
    at Module.load (node:internal/modules/cjs/loader:972:32)
    at Function.Module._load (node:internal/modules/cjs/loader:813:14)
    at Module.require (node:internal/modules/cjs/loader:996:19)
    at require (node:internal/modules/cjs/helpers:92:18)
    at DevServer.handleApiRequest (/home/user/app/client/node_modules/next/dist/next-server/server/next-server.js:64:181)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (node:internal/process/task_queues:94:5)
    at async Object.fn (/home/user/app/client/node_modules/next/dist/next-server/server/next-server.js:56:492)
    at async Router.execute (/home/user/app/client/node_modules/next/dist/next-server/server/router.js:23:67)
    at async DevServer.run (/home/user/app/client/node_modules/next/dist/next-server/server/next-server.js:66:1042)
Run Code Online (Sandbox Code Playgroud)

第二次尝试 ( next.config.js):

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

这东西根本不起作用。

第三次尝试(带有next-http-proxy-middleware):

// pages/[...all].ts
...
export default (req: NextApiRequest, res: NextApiResponse) => (
  isDevelopment
    ? httpProxyMiddleware(req, res, {
      // You can use the `http-proxy` option
      target: 'https://www.example.com',
      // In addition, you can use the `pathRewrite` option provided by `next-http-proxy`
      pathRewrite: {
        '^/api/new': '/v2',
        '^/api': '',
      },
    })
    : res.status(404).send(null)
);
Run Code Online (Sandbox Code Playgroud)

这东西根本没有文档......不知道它是如何工作的。

第四次尝试(使用自定义的 Next 服务器):

const express = require('express')
const next = require('next')
const { createProxyMiddleware } = require("http-proxy-middleware")

const port = process.env.PORT || 3000
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()

const apiPaths = {
    '/api': {
        target: 'http://localhost:3080', 
        pathRewrite: {
            '^/api': '/api'
        },
        changeOrigin: true
    }
}

const isDevelopment = process.env.NODE_ENV !== 'production'

app.prepare().then(() => {
  const server = express()
 
  if (isDevelopment) {
    server.use('/api', createProxyMiddleware(apiPaths['/api']));
  }

  server.all('*', (req, res) => {
    return handle(req, res)
  })

  server.listen(port, (err) => {
    if (err) throw err
    console.log(`> Ready on http://localhost:${port}`)
  })
}).catch(err => {
    console.log('Error:::::', err)
})
Run Code Online (Sandbox Code Playgroud)

这会在下一个应用程序中快速运行。我需要将下一个应用程序和服务器分开。这不是我想要的。

小智 12

使用next-http-proxy-middleware你可以轻松代理nextjs中的api。

首先,看看如何在nextjs中使用api。-https://nextjs.org/docs/api-routes/api-middlewares

  1. [...all].ts{yourproject_root}/pages/api/项目根路径的路径中创建一个文件。
  2. 复制下面的代码并将其写入[...all].ts文件中。
export default (req: NextApiRequest, res: NextApiResponse) => httpProxyMiddleware(req, res, {
     // You can use the `http-proxy` option
     target:'https://www.example.com',
     // In addition, you can use the `pathRewrite` option provided by `next-http-proxy`
     pathRewrite: {
     '^/api/google':'https://google.com',
     '^/api/myhome':'https://github.com/stegano'
     },
});
Run Code Online (Sandbox Code Playgroud)
  1. 运行 nextjs,打开浏览器,然后尝试连接到localhost:3000/api/googlelocalhost:3000/api/myhome


小智 10

在 v9.5.0 版本中,next 添加了重写,这使我们的代理生活变得更轻松。

const isDevelopment = process.env.NODE_ENV !== "production";
const rewritesConfig = isDevelopment
  ? [
      {
        source: "/cats",
        destination: process.env.CATS_ENDPOINT,
      },
    ]
  : [];

module.exports = {
  reactStrictMode: true,
  rewrites: async () => rewritesConfig,
};
Run Code Online (Sandbox Code Playgroud)

只需在next.config.js文件中添加重写异步函数,该函数返回包含代理的对象数组。process.env.CATS_ENDPOINT如果您不希望将端点设置为环境变量,则可以在示例中替换为任何绝对 url。

  • 与/sf/answers/4582740361/相关 (2认同)