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

如何禁用NestInterceptor自动序列化?自定义响应拦截器数据序列化问题

问题:NestInterceptor包装响应后data被序列化为字符串的解决方法

我用以下NestInterceptor给最终响应统一添加code、message和data字段:

export class HttpResponseInterceptor implements NestInterceptor {
    intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
        return next.handle().pipe(map(data => ({
                code: 200,
                message: 'ok',
                data: data
            }))
        );
    }
}

期望得到的响应格式:

{
    "code": 200,
    "message": "ok",
    "data": {
        "vip": 333,
        "enterprise": 14,
        "pension": 712
    }
}

但实际得到的结果里,data变成了JSON字符串:

{
    "code": 200,
    "message": "ok",
    "data": "{\"vip\":333,\"enterprise\":14,\"pension\":712}"
}

补充说明:移除GlobalFilters无效,当前仅启用了这个GlobalInterceptors。


解决方法

1. 检查控制器的返回逻辑

这是最常见的原因:你的控制器可能已经手动把响应数据序列化为字符串了(比如用了JSON.stringify(),或者直接调用res.send(JSON.stringify(...))),导致Interceptor拿到的是字符串而非原始对象。

修正方式:控制器直接返回JavaScript对象,不要手动序列化。比如:

// 正确写法
@Get('/data')
getData() {
  return {
    vip: 333,
    enterprise: 14,
    pension: 712
  };
}

// 错误写法(会导致Interceptor拿到字符串)
@Get('/data')
getData(@Res() res) {
  res.send(JSON.stringify({ vip: 333, ... }));
}

2. 在Interceptor中手动解析字符串(应急方案)

如果无法修改控制器的返回逻辑(比如依赖第三方代码),可以在Interceptor里判断data类型,尝试将字符串解析为对象:

export class HttpResponseInterceptor implements NestInterceptor {
    intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
        return next.handle().pipe(map(data => {
            let parsedData = data;
            // 仅当data是字符串时尝试解析
            if (typeof data === 'string') {
                try {
                    parsedData = JSON.parse(data);
                } catch (err) {
                    // 解析失败则保留原数据,避免报错
                }
            }
            return {
                code: 200,
                message: 'ok',
                data: parsedData
            };
        }));
    }
}

3. 避免直接操作响应对象

如果控制器中使用了@Res()装饰器直接操作响应对象,会绕过Nest的默认序列化机制,导致返回字符串。这种情况下应该尽量使用Nest的标准返回方式,或者在使用@Res()时加上{ passthrough: true }参数,让Nest继续处理响应:

@Get('/data')
getData(@Res({ passthrough: true }) res) {
  // 可以操作res的其他属性,但返回对象交给Nest处理
  res.setHeader('X-Custom-Header', 'value');
  return { vip: 333, ... };
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 00:20:30