[英]How to escape angular HttpParams?
在 Angular 服務中,我使用 HttpParams 向服務發送字符串:
get(phone: string): Observable<PhoneSearchResponse> {
let params = new HttpParams();
params = params.append("phone", phone); // sending "+123456"
return this._http.get<PhoneSearchResponse>(`${this._apiurl}/Get`, { params: params });
}
當使用+123456
作為參數調用 get() 時,我將在接收服務中得到123456
。 因此,在+
轉換為空格的途中某處。
我是否需要轉義 HttpParams 才能使它們對服務保持不變?
如果重要的話,后端是一個 asp.net 核心項目。 控制器中調用代碼:
[HttpGet("[action]")]
public async Task<JsonResult> Get(string phone) // receiving " 123456"
{
return Json(await PhoneSearchLogic.GetAsync(phone));
}
[更新] Noémi Salaün 的解釋非常好 - 但我想知道更改參數是否是“設計”的預期行為? 或者是 ASP.NET Core 控制器的問題,它不應該取消 + 符號(和其他)?
正如您在源代碼common/http/src/params.ts中看到的, HttpParams
使用默認編碼器HttpUrlEncodingCodec
。
HttpUrlEncodingCodec
使用本機encodeURIComponent
函數,但隨后取消編碼某些符號以滿足 RFC 規范(不遵循本機 JS 實現)。
因此,如果您想保持您的+
符號編碼,您可以在使用HttpParams
之前手動對其進行編碼,或者您可以使用自己的實現覆蓋HttpParameterCodec
並通過HttpParamOptions.encoder
屬性傳遞它。
所有這些在現已棄用的Http
服務中得到了更好的解釋。 使用它的UrlSearchParams
和QueryEncoder
。
正如您在源代碼http/src/url_search_params.ts中看到的
默認情況下,
QueryEncoder
使用encodeURIComponent
對參數的鍵和值進行編碼,然后根據 IETF RFC 3986 對允許成為查詢一部分的某些字符進行取消編碼: https ://www.rfc-editor.org/rfc/rfc3986 .這些是未編碼的字符:
! $ \' ( ) * + , ; A 9 - . _ ~ ? /
! $ \' ( ) * + , ; A 9 - . _ ~ ? /
如果特定后端不允許允許的查詢字符集,則可以將
QueryEncoder
子類化並作為 URLSearchParams 的第二個參數提供。
Angular 13 仍然存在這個問題。 查看https://github.com/angular/angular/issues/11058和https://github.com/angular/angular/pull/45111
對我有用的解決方案由 Ali Kamalizade 在https://betterprogramming.pub/how-to-fix-angular-httpclient-not-escaping-url-parameters-ddce3f9b8746編寫
以下是他的解決方案。 Noémi Salaün 在這個問題的公認答案中提出了相同的解決方案。
import { HttpParameterCodec } from '@angular/common/http';
export class CustomHttpParamEncoder implements HttpParameterCodec {
encodeKey(key: string): string {
return encodeURIComponent(key);
}
encodeValue(value: string): string {
return encodeURIComponent(value);
}
decodeKey(key: string): string {
return decodeURIComponent(key);
}
decodeValue(value: string): string {
return decodeURIComponent(value);
}
}
您可以在創建 HttpParams 時使用它。
new HttpParams({ encoder: new CustomHttpParamEncoder() })
編輯:這已在版本 14 中修復。請參閱https://github.com/angular/angular/blob/main/CHANGELOG.md#http-1 https://blog.angular.io/angular-v14-is-now -available-391a6db736af
而是一個純 Javascript 解決方案,
const string = 'text+that+has+plus+signs';
為了安全編碼,(請注意encodeURIComponent
很重要,因為btoa
可以返回+
)
const enc = encodeURIComponent(btoa(string));
console.log(enc); //dGV4dCt0aGF0K2hhcytwbHVzK3NpZ25z
要解碼並取回純文本,
const dec = atob(decodeURIComponent(enc));
console.log(dec); //text+that+has+plus+signs
我真的不喜歡重寫HttpUrlEncodingCodec
只是為了在 post 參數中轉義+
符號。
我希望這會對某人有所幫助。 干杯:)
我前段時間遇到了這個問題,最后決定使用 FormData 而不是 HttpParams ......幾乎無處不在。 我曾經依賴 FormData,尤其是在將文件發送到服務時,直到我使用 HttpParams 發送了一個帶有 + 符號的字符串,並且 + 從未到達后端; 它被一個空格所取代。
所以只需更換
let params = new HttpParams();
params = params.append("phone", phone); // sending "+123456"
和
let params = new FormData();
params.append("phone", phone);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.