繁体   English   中英

如何 HTTP 代理 Next.js API 请求

[英]How to HTTP proxy for Next.js API requests

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

首先尝试( 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!`);
    });
};

给我这样的错误:

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)

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

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

这东西根本行不通。

第三次尝试(使用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)
);

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

第四次尝试(使用自定义 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)
})

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

在 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,
};

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

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

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

  1. 在项目根路径的{yourproject_root}/pages/api/路径中创建一个[...all].ts文件。
  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'
     },
});
  1. 运行 nextjs,打开浏览器,尝试连接到localhost:3000/api/googlelocalhost:3000/api/myhome

实际上,您的第一次尝试对我next@12.1.2

这是我的确切代码(但与您的代码几乎相同):

// 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 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!`
    );
  });
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM