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

Angular 2 中如何拦截并预处理JSON响应内的裸Infinity、NaN值?

拦截器失效的根本原因

你当前代码执行不到console.log("HERE")的核心逻辑是:Angular默认对所有出站请求使用responseType: 'json'配置,拿到XHR响应后会直接在内置流程中调用原生JSON.parse()做反序列化。当响应中存在裸Infinity值时,原生解析会直接抛出语法错误,这个错误发生在你的拦截器管道下游的内置环节,根本不会把HttpResponse对象传递到你写的map逻辑中,自然你的自定义代码永远没有执行机会。

可行实现方案

完全可以实现在Angular内置JSON反序列化前修改原始响应文本,核心思路是把响应解析的控制权从Angular内置逻辑转移到你的拦截器管道中,整体流程为:

  • 拦截出站请求,将请求的responseType从默认json修改为text,强制Angular跳过内置JSON解析环节,直接把原始响应文本返回给拦截器
  • 拿到原始文本后,先执行自定义的预处理逻辑,把不合规的裸Infinity、-Infinity替换为符合JSON语法规范的可解析标记
  • 对预处理后的合规文本手动执行JSON.parse(),在解析的reviver回调中把之前替换的标记值还原为原生JS的Infinity对象
  • 将解析完成的正常对象回填到HttpResponse的body字段,继续往下游的业务服务传递
修正后的可运行实现
// 原始响应文本预处理函数:替换不合规的裸Infinity值
function replaceInfinity(rawText: string): string {
    return rawText
        // 匹配键值对中未被引号包裹的裸正Infinity
        .replace(/:\s*Infinity\b/g, ': "__POSITIVE_INFINITY__"')
        // 匹配键值对中未被引号包裹的裸负Infinity
        .replace(/:\s*-Infinity\b/g, ': "__NEGATIVE_INFINITY__"');
}

@Injectable()
export class JsonInfinityTranslator implements HttpInterceptor {
    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        // 修改出站请求配置,强制返回纯文本,跳过内置JSON解析
        const textModeReq = req.clone({ responseType: 'text' });

        return next.handle(textModeReq).pipe(
            map((event) => {
                if (event instanceof HttpResponse) {
                    // 此处可正常打印日志,因为请求不会在内置解析环节触发错误
                    console.log("HERE");
                    const rawResponseText = event.body as string;
                    // 文本预处理
                    const cleanedValidJsonText = replaceInfinity(rawResponseText);
                    // 手动执行JSON解析,在reviver中还原Infinity值
                    const parsedBody = JSON.parse(cleanedValidJsonText, (_, value) => {
                        if (value === "__POSITIVE_INFINITY__") return Infinity;
                        if (value === "__NEGATIVE_INFINITY__") return -Infinity;
                        return value;
                    });
                    // 将解析完成的对象回填到响应体,继续管道流转
                    return event.clone({ body: parsedBody });
                }
                // 透传其他类型的HttpEvent(比如上传进度、下载进度事件)
                return event;
            })
        );
    }
}
实现注意事项
  • 所有业务侧的请求逻辑完全不需要改动:拦截器会自动对所有请求做配置切换,业务服务拿到的响应对象结构和值与原生处理逻辑完全一致,Infinity值会被正确还原,可直接在业务代码中判断、使用
  • 不需要引入第三方JSON解析库:整个流程完全基于原生JS能力实现,逻辑和大多数支持Infinity的JSON扩展库的实现思路一致
  • 错误响应兼容:如果需要处理接口报错场景的响应内容,只需在管道中补充catchError分支,对错误响应的文本体执行同样的预处理、解析流程即可
  • 正则匹配的边界优化:实际使用时可以根据API返回的文本格式调整replaceInfinity中的正则规则,避免误匹配字符串中出现的Infinity文本

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.30 23:06:07