Angular14升级后HTTP URL参数+被编码为%2B致接口报错如何解决
Angular 14升级后HttpClient查询参数中+号被编码为%2B的解决方法
问题表现
- Angular 13环境下正常发起的请求URL:
domain.com/api/v2/todos/count?filter=created+ge+1997-06-21 - 升级Angular 14后同逻辑发起的请求URL:
domain.com/api/v2/todos/count?filter=created%2Bge%2B1997-06-21 - 触发原因:Angular 14调整了内置
HttpClient的查询参数默认序列化逻辑,会对参数值中的+做标准百分号编码转为%2B,若后端未兼容标准URL编码规则、仅识别未编码的+,就会出现接口调用失败。
问题复现的原始代码
component.ts
const filter = "created+ge+1997-06-21" service.todosCount(filter).subscribe()
service.ts
todosCount(params) { return this.http.get<TodosCount[]>( '/afes_case_api/v1/cases/state_count',{ params } ) }
解决方法
方法1:自定义参数编码器(推荐,不影响全局其他请求)
实现HttpParameterCodec接口,自定义编码逻辑保留+不被转义,仅在需要兼容的接口中使用即可:
import { HttpParameterCodec, HttpParams } from '@angular/common/http'; // 自定义编码器,保留字面量+不被编码 class CustomQueryEncoder implements HttpParameterCodec { encodeKey(key: string): string { return encodeURIComponent(key).replace(/%2B/gi, '+'); } encodeValue(value: string): string { return encodeURIComponent(value).replace(/%2B/gi, '+'); } decodeKey(key: string): string { return decodeURIComponent(key.replace(/\+/gi, ' ')); } decodeValue(value: string): string { return decodeURIComponent(value.replace(/\+/gi, ' ')); } }
调整service层的传参逻辑,给对应接口的HttpParams指定自定义编码器:
todosCount(filterValue: string) { const params = new HttpParams({ encoder: new CustomQueryEncoder(), object: { filter: filterValue } }) return this.http.get<TodosCount[]>( '/afes_case_api/v1/cases/state_count', { params } ) }
方法2:手动拼接请求URL(适用于少量特殊接口)
如果仅单个接口需要兼容,也可以直接拼接完整请求路径,跳过HttpClient的默认参数序列化流程,注意自行处理其他特殊字符的编码即可:
todosCount(filterValue: string) { const requestUrl = `/afes_case_api/v1/cases/state_count?filter=${filterValue}`; return this.http.get<TodosCount[]>(requestUrl); }
补充说明:按照URL编码标准规范,查询参数中的
+默认代表空格,字面量+的标准编码结果就是%2B。长期建议推动后端兼容标准编码逻辑,避免后续框架迭代、更换HTTP客户端时重复出现兼容问题。
内容的提问来源于stack exchange,提问作者Arun M
相关产品推荐
相关产品推荐

