AWS API Gateway HTTP API未返回application/json内容类型问题
AWS SAM HTTP API 返回Content-Type为text/plain而非application/json的问题及解决方法
问题描述
使用AWS SAM构建基于Lambda的API,从Rest API转为HTTP API后,接口返回的Content-Type变为text/plain,而非预期的application/json。原本认为HTTP API默认应返回application/json,查阅文档多聚焦于Rest API的内容类型修改,未找到HTTP API相关方法。当前template.yaml配置如下:
Resources: ApiGatewayApi: Type: AWS::Serverless::HttpApi Properties: StageName: Prod UsersFunctionGet: Type: AWS::Serverless::Function Properties: FunctionName: UsersFunctionGet CodeUri: function-users/ Handler: src/handlers/users-get.handler Runtime: nodejs18.x Architectures: - x86_64 Events: UsersEvent: Type: HttpApi Properties: Path: / Method: get ApiId: !Ref ApiGatewayApi UserEvent: Type: HttpApi Properties: Path: /{user_id} Method: get ApiId: !Ref ApiGatewayApi Policies: - DynamoDBCrudPolicy: TableName: !Ref UsersTable Environment: Variables: USERS_TABLE: !Ref UsersTable FunctionUrlConfig: AuthType: NONE # AWS_IAM Metadata: BuildMethod: esbuild BuildProperties: Minify: true Target: es2020 Sourcemap: true EntryPoints: - src/handlers/users-get.ts APIMapping: Type: AWS::ApiGatewayV2::ApiMapping Properties: ApiMappingKey: 'users' ApiId: !Ref ApiGatewayApi Stage: !Ref ApiGatewayApi.Stage
原因分析
HTTP API的内容类型推断逻辑和Rest API存在差异:
- 若Lambda直接返回JavaScript对象,HTTP API会自动将其序列化为JSON字符串,并设置
Content-Type: application/json。 - 若Lambda返回的是JSON格式的字符串(比如通过
JSON.stringify()转换后的结果),HTTP API会将其识别为纯文本,默认设置Content-Type: text/plain。 - 之前使用Rest API时,可能默认配置了响应模板自动处理JSON字符串,而HTTP API的代理集成不会做额外格式转换。
解决方法
方法1:修改Lambda代码,返回带headers的完整响应对象
这是最直接且推荐的方式,在Lambda handler中显式指定Content-Type头,返回符合API Gateway代理集成要求的响应结构:
export const handler = async (event: any): Promise<any> => { // 业务逻辑,获取数据 const data = { users: [...] }; return { statusCode: 200, headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) }; };
返回该结构后,HTTP API会严格遵循你设置的headers,确保Content-Type为application/json。
方法2:在SAM模板中配置HTTP API的响应参数(无需修改Lambda代码)
如果不想调整Lambda代码,可以在ApiGatewayApi的配置中添加默认集成响应参数,强制设置Content-Type:
ApiGatewayApi: Type: AWS::Serverless::HttpApi Properties: StageName: Prod DefaultIntegration: PayloadFormatVersion: '2.0' ResponseParameters: Headers: Content-Type: "'application/json'"
该配置会为所有路由的响应强制添加Content-Type: application/json头,无论Lambda返回的是对象还是字符串。
内容的提问来源于stack exchange,提问作者Nolan Watts
相关产品推荐
相关产品推荐

