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

问题相关代码
路由定义文件 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
相关产品推荐
相关产品推荐

