You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Postman向Hapi框架API发送POST请求时持续挂起无响应

问题现象
  • 使用Postman调试Hapi框架开发的接口时,POST类请求会一直卡在「sending request」状态无响应
  • 出问题的路由对应handler仅做简单的路径参数返回,无复杂业务逻辑,依然无法正常返回结果
  • 同一路由保持其他配置不变,仅将请求方法改为GET即可正常响应;改为POST、PUT、PATCH方法时均会出现无限挂起问题
  • 挂起状态无自动超时提示,参考截图:Postman请求挂起界面
问题相关代码

路由定义文件 currency.ts

//this is where i define the route methods and paths

import * as Hapi from "hapi";
import IRouteArea from "../server/IRouteArea";
import CurrencyController from "../controller/CurrencyController";
import hapiAuthJwt2 = require("hapi-auth-jwt2");
import { join } from "lodash";
import { RESOLVER } from "awilix";

const CurrencyArea = ({ currencyController }: any): IRouteArea => {
  let _controller = currencyController as CurrencyController;
  return {
    registerRoutes(server: Hapi.Server) {
      server.bind(_controller);
      
      server.route({
        method: "GET",
        path: "/api/currencies",
        options: {
          auth: {
            mode: "try"
          },
          plugins: { "hapi-auth-cookie": { redirectTo: false } },
          handler: _controller.getCurrencies
        }
      });
      server.route({
        method: "POST",  // this one is causing me problems
        path: "/api/currencies/{id}",
        options: {
          auth: {
            mode: "try"
          },
          plugins: { "hapi-auth-cookie": { redirectTo: false }},         
          handler: _controller.editCurrency
        }
      });
    }
  };
};

export default CurrencyArea;

控制器文件 CurrencyController.ts

//here i define the handlers of requests sent to routes in the previous file

import * as Hapi from "hapi";
import { name } from "mustache";
import GetCurrencyListInteractor from "../../interactor/currencies/GetCurrencyListInteractor";
import Task from "../../runtime/Task";

export default class CurrencyController {
  private task: Task;

  constructor({ task }: any) {
    this.task = task;
  }

  public async getCurrencies(
    request: Hapi.Request,
    h: Hapi.ResponseToolkit
  ): Promise<any> {
    try {
       return this.task.start<GetCurrencyListInteractor>(
        "getCurrencyList",
        t => t.execute()
      ); 
    } catch (error) {
      return error as any;
    }
  }
  

  public async editCurrency( //it's supposed to just return the parameter sent in the url
    request: Hapi.Request,
    h: Hapi.ResponseToolkit
  ): Promise<any> {
    try {
      return request.params.id;
    } catch (error) {
      return error as any;
    }
  }
}
问题原因

Hapi框架的请求处理生命周期中,对POST、PUT、PATCH这类携带请求体的请求,会默认在进入handler逻辑前,先完成请求体的接收与解析流程。如果客户端发送的请求头声明了存在请求体,但实际没有完成请求体内容的传输,服务端会持续等待数据传输完成,表现为请求一直挂起,不会进入业务处理逻辑。
GET、HEAD类请求默认不携带请求体,不会触发这一步等待逻辑,因此可以正常响应。

解决方案

按实际场景选择对应处理方式即可:

  • 调试阶段检查Postman配置:如果该接口不需要传请求体,将Postman请求的Body选项切换为none,避免工具自动添加不匹配的Content-Length或Transfer-Encoding头,导致服务端误判存在待接收的请求体。
  • 接口本身不需要处理请求体时,直接在路由配置中关闭默认的请求体解析逻辑,修改POST路由配置如下:
server.route({
  method: "POST",
  path: "/api/currencies/{id}",
  options: {
    auth: {
      mode: "try"
    },
    plugins: { "hapi-auth-cookie": { redirectTo: false }},
    // 新增payload配置,关闭自动解析
    payload: {
      parse: false
    },
    handler: _controller.editCurrency
  }
});
  • 接口需要接收请求体时,明确配置允许的请求体格式,例如接收JSON参数时添加配置:
payload: {
  parse: true,
  allow: 'application/json'
}

同时确认Postman发送请求时选择了匹配的Body类型,填写了合法的请求内容。

  • 如果服务前部署有Nginx等反向代理,检查代理配置,确认没有对POST请求开启不合理的请求缓冲规则,避免请求体被代理拦截未转发到Hapi服务。

内容的提问来源于stack exchange,提问作者Fuad Jaganjac

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 09:57:27