簡體   English   中英

如何轉義有角度的 HttpParams?

[英]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服務中得到了更好的解釋。 使用它的UrlSearchParamsQueryEncoder

正如您在源代碼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/11058https://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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM