为什么仅针对 POST 请求,Firebase 上托管的 NextJs 应用会收到“502 Gateway”错误?

2024-03-13

我开始使用 NextJs 框架构建 API。我希望将其托管在 Firebase 上(托管和功能)。只要我只发送 GET 请求,一切就正常。当我发送 POST 请求时,我收到一个“502错误的网关” error.

复制起来非常简单。您只需下载并部署 NextJs 开发团队提供的示例。

  • 创建一个新项目Firebase https://console.firebase.google.com/ console

  • 安装“使用 Firebase 托管 https://github.com/vercel/next.js/tree/canary/examples/with-firebase-hosting“ 例子

  • 更改项目名称.firebaserc(第 3 行) https://github.com/vercel/next.js/blob/canary/examples/with-firebase-hosting/.firebaserc#L3 file

  • 创建一个文件夹"api"文件夹下"pages"

  • 创建一个文件“你好.js”文件夹下"api"并添加以下代码片段

    export default async (req, res) => {
      const {
        body,
        method
      } = req;
    
      console.log("method :>> ", method);
      console.log("body :>> ", body);
    
      switch (method) {
      case "POST":
        res.status(200).end(`Method ${method} supported!`);
        break;
      default:
        res.setHeader("Allow", ["POST"]);
        res.status(405).end(`Method ${method} Not Allowed`);
      }
    };
    
    
  • 部署应用程序

  • 发送 GET 请求到“https://[project-name].web.app/api/hello”并查看它是否有效

  • 发送 POST 请求到“https://[project-name].web.app/api/hello”并查看它不起作用

有和我一样的错误吗?

我花了两天时间阅读文章、观看视频并尝试不同的配置。您甚至可以更新firebase函数 https://github.com/vercel/next.js/blob/canary/examples/with-firebase-hosting/firebaseFunctions.js#L16添加一个console.log并看到 POST 请求被 Firebase Cloud Function 捕获,但 NextJs 服务器不会像 GET 请求那样将其传递给我们的 API。这超出了我的能力范围...

在你应该有的输出下面。 POST 请求应得到答复200 - Method POST is supported!.


追踪起来确实很痛苦,但在自己研究了一段时间后,我发现 PUT 和 PATCH 请求也会出现同样的问题。这表明它与请求的正文有关。令人烦恼的是,在发现这一点后,我偶然发现了这条线问题#7960 https://github.com/vercel/next.js/issues/7960,他们发现了同样的问题。

简单地说,请求的正文被处理一次https.onRequest()进而nextjsHandle()尝试再次解析它。因为尸体已经被处理过了raw-body模块(内nextjsHandle()) 无限期地等待'data'永远不会发生的事件。

目前,没有办法关闭由https.onRequest(),因此必须在 next.js 端禁用它。不幸的是,没有可以添加的用于正文解析的全局关闭开关next.config.js并且必须对每个 API 路由(中的文件)执行此操作pages/api)(如果建议的修复方案可能会改变公关#16169 https://github.com/vercel/next.js/pull/16169被添加)。

要禁用给定路由的正文解析,请将以下内容添加到路由的文件中

export const config = {
  api: {
    // disables call to body parsing module
    bodyParser: false,
  }
};

然而,正如中提到的问题#7960 https://github.com/vercel/next.js/issues/7960 by @rscotten https://github.com/rscotten,您可能还想使用next dev在开发您的应用程序时,因此您需要在使用时启用它next dev但在部署时禁用它。这可以使用以下方法完成

export const config = {
  api: {
    // disables call to body parsing module while deployed
    bodyParser: process.env.NODE_ENV !== 'production',
  }
};

将这些更改应用到hello.js gives:

export default async (req, res) => {
  const {
    body,
    method
  } = req;

  console.log("method :>> ", method);
  console.log("body :>> ", body);

  switch (method) {
  case "POST":
    res.status(200).end(`Method ${method} supported!`);
    break;
  default:
    res.setHeader("Allow", ["POST"]);
    res.status(405).end(`Method ${method} Not Allowed`);
  }
};

export const config = {
  api: {
    // disable nextjs's body parser while deployed
    // (as body parsing is handled by `https.onRequest()`),
    // but enable it for local development using `next dev`
    bodyParser: process.env.NODE_ENV !== 'production',
  }
};
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么仅针对 POST 请求,Firebase 上托管的 NextJs 应用会收到“502 Gateway”错误? 的相关文章

随机推荐