簡體   English   中英

帶有主體的 Angular HttpClient Get 方法

[英]Angular HttpClient Get method with body

我正在改進現有的 API,並且要求提供一個可以接受多個搜索條件並根據這些條件執行查詢的單一 get 方法。

我正在使用 Spring MVC。 get 方法簽名:

@GetMapping("/subscribers")
public ResponseEntity<List<SubscriberDTO>> getAllSubscribers(Pageable pageable, @RequestBody List<SearchCriteria> lstSearchCriteria)

該實現按預期在 Postman 上進行了測試

現在我要去 Angular 來實現前端,但我找不到通過 HttpClient Get 方法發送主體的方法......

我有點卡住了。 我應該通過標題發送搜索條件嗎? 或者有更好的方法嗎?

據我所知,您不能使用 HttpClient get 發送正文。 您至少可以使用查詢使其成為慣用語。 (或者您可以嘗試以某種方式強制解決問題)。

假設您有一個符合條件的數組:

const criteria = [ {a: 25}, {b: 23} ];
http.get(url + '/?criteria='+ encodeURIComponent( JSON.stringify(criteria)));

在 GET 請求中發送正文違反了某些 RFC 標准,即使它可能有效,您也一定會召喚一些神秘的惡魔。

在服務方法中,您可以使用如下所示的方法,該方法采用搜索查詢的可選參數。 您可以通過 Observe 發送您的搜索參數,如下所示。

getAllSubscribers(
    page?,
    itemsPerPage?,
    userParams?
  ): Observable<PaginatedResult<Subscribers[]>> {
    const paginatedResult: PaginatedResultSubscribers[]> = new PaginatedResult<
      Subscribers[]
    >();

    let params = new HttpParams();

    if (page != null && itemsPerPage != null) {
      params = params.append("pageNumber", page);
      params = params.append("pageSize", itemsPerPage);
    }

    if (userParams != null) {
      params = params.append("minAge", userParams.minAge);
      params = params.append("maxAge", userParams.maxAge);
        }

       return this.http
      .get<Subscribers[]>(this.baseUrl + "/subscribers", { observe: "response", params })
      .pipe(
        map(response => {
          paginatedResult.result = response.body;
          if (response.headers.get("Pagination") != null) {
            paginatedResult.pagination = JSON.parse(
              response.headers.get("Pagination")
            );
          }
          return paginatedResult;
        })
      );
  }

基本思想是使用HttpParams。

為了讓 Amir 的回答更通用,我做了以下工作來為傳遞的項目構建參數。

在我的通用數據服務中,我添加了這個變體:

// Get data for passed parameters or item containing filters
public getByItem<T>(apiMethod: string, item?: T, apiParms?: HttpParams): Observable<T> {
    if (!apiParms) apiParms = new HttpParams();
    if (item) {
        const keys = Object.keys(item) as Array<keyof T>;
        for (let key of keys) {
            apiParms = apiParms.append(key.toString(), item[key].toString());
        }
    }
    // Call generic method of data service
    return this.get<T>(apiMethod, apiParms); // => return this.http.get<T>(environment.apiUrl + apiMethod, { headers: this.defaultHeaders

只是為了澄清這里的一些答案,首先,如前所述,Angular 不支持為主體提供 GET 請求,並且沒有辦法解決這個問題。 其原因不是 Angular 的錯,而是 XMLHttpRequest (XHR) 的錯,瀏覽器用於發出請求的 API。 XHR 不支持帶有 GET 請求的正文。

當前的 HTTP 標准中沒有任何內容表明帶有 GET 請求的 Body 是無效的,只是在語義上沒有明確定義。

就 REST 而言,在我看來,為主體提供 GET 請求比使用 POST 更可取。 所以有點煩人的是XHR不支持這個。

對我有用:

import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http'; 

filterBooks(category: string, year: string): Observable<Book[]> {
   let httpHeaders = new HttpHeaders()
                         .set('Accept', 'application/json');
   let httpParams = new HttpParams()
                        .set('category', category)
                    .set('year', year);
   console.log(httpParams.toString());
   console.log(httpHeaders.keys());
   return this.http.get<Book[]>(this.bookUrl, {
                headers: httpHeaders,
                params: httpParams, 
                responseType: 'json'
        });
} 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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