使用 Angular 的 HttpClient 时,如何使用 URI 中的矩阵参数向后端发出请求?

How do you make a request with matrix parameters in the URI to a backend when using Angular's HttpClient?

矩阵参数一直在since the late 90ies, and Angular's RouterModule knows how to deal with requests containing them. Nowadays, I would say they are a defacto standard左右。鉴于此,我想知道 Angular 的 HttpClient 是否以类似于 HttpParams 支持查询参数的方式支持它们(使用 URL 编码值)?

到目前为止,我只找到 issue from 2014 for AngularJS (not Angular) about when to encode semicolons 中的评论。

是在 Angular 的 HTTP 请求(到后端)中使用矩阵参数 的唯一方法,因此 建立URL "manually",例如使用字符串插值,而 query params can be added to a request as the params property of type HttpParams via the HttpClientoptions 对象?

(换句话说,Angular 似乎处理 URL-编码并为查询参数添加问号、等号和符号 - 它可以为矩阵参数做等效的事情吗?)

在请求中使用矩阵参数的 clean/Angular 方式是什么(URL 矩阵参数值的编码是否会由 HttpClient 及其依赖项自动处理,或者是开发人员必须明确做的事情)?

到目前为止我们知道它没有得到官方支持。

但我认为 HttpInterceptor 可以在这里工作。不过我没试过:

import {
  HttpInterceptor,
  HttpRequest,
  HttpHandler,
  HttpEvent
} from "@angular/common/http";
import { Observable } from "rxjs";

export class MatrixParamInterceptor implements HttpInterceptor {
  intercept(
    req: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    const cloneReq = req.clone({
      params: null, // should be already present in urlWithParams
      url: mapToMatrixParams(req.urlWithParams) 
    });
    return next.handle(cloneReq);
  }
}

urlWithParamsHttpRequest 的构造函数中求值。 HttpClient 创建我们在拦截器中修改的初始 HttpRequest

HttpRequest class.

HttpClient class.

Angular's RouterModule knows how to deal with requests containing them

有点知道如何处理它们,因为这是支持多个活动路由的副作用。

在文档的更下方,它谈到了 named outlets:

https://angular.io/guide/router#displaying-multiple-routes-in-named-outlets

基本上,路由器可以同时激活一条或多条路由。这对于 URL 是不可能的,因此解决方法是将命名路由注入 编码到 URL 路径 .

因此可以使用以下 URL:

激活命名插座
http://.../crisis-center(popup:compose)

以上利用字符 (:) 是有效的 URL 字符。这与我们用来创建矩阵参数的副作用相同,您可以看到 Angular 团队通过使用不同的语法故意避免与矩阵参数发生冲突。

I was wondering if Angular's HttpClient supports them (with URL-encoded values) in a way similar to how it supports query parameters with HttpParams?

URL 规范声明只能有 一个 查询参数。

矩阵参数并非如此。

http://example.com/a;first=1/b;second=2/c;third=3

上面的例子表明有三组不同的矩阵参数。 Web 服务器将按如下方式读取这些内容:

a?first=1
b?second=2
c?third=3

URL 路径和参数之间存在紧密耦合。由于 URL 是 HttpClient 方法的单个参数。不可能(不更改 API)单独传递矩阵参数。

Put differently, Angular seems to deal with URL-encoding and adding question mark, equal signs and ampersands for query params - can it do the equivalent for matrix params?

我确定您可以创建某种可以对矩阵参数进行编码的 API,但它将处于 URL 级别。这意味着 URL 字符串将是一个程序值,使 API 不太用户友好。

还有多种使用矩阵参数的模式。 Java、C#、Python 等...等都有不同的框架。

What's the clean/Angular way of using matrix parameters in requests

没有一个。这只是另一个 URL 字符串。

(and will URL encoding of the matrix parameter values be taken care of automagically by HttpClient and its dependencies or is that something the dev has to do explicitly)?

您不能对 URL 进行编码,而 HttpClient 接收 URL 作为第一个参数。这是发生的情况的示例。

console.log(encodeURIComponent('https://www.example.com/'));

由于矩阵参数是 URL 的一部分(在查询之前),因此您需要创建一个有效的 URL.

所以基本上,回答你的问题。在调用 HttpClient.get()

之前,您需要自己的实用程序来生成 URL
function encodeMatrix(url: string, params: any) {
  // do work
  return url;
}

httpClient.get(encodeMatrix("https://www.example.com/", myParams)).subscribe()