Angular 6 Http客户端自定义URL和标头

法比奥·卡瓦略(Fabio Carvalho)

我在Angular 6应用程序中工作,我想知道在将请求发送到服务器时自定义url时最好的做法是什么。

这是场景:-在我的Angular项目中,我有environment.ts和environment.prod.ts,在其中添加了一个“主机”,其中包含http服务器的url:port(带有控制器的项目)。-我正在创建要注入到我的组件中的服务,这些组件将负责向服务器发送请求(GET和POST)以检索数据或发送更新。-我想使用environment.ts中的“主机”作为请求网址的一部分。因此,我的所有请求都将“主机”作为基本URL,然后我可以将其连接到所需的路径。

我已经检查了一些解决方案,并且已经实施了其中一种,但是我不确定这是正确的做法。我将在下面介绍到目前为止已实现的内容,然后再写一些想法,请帮助我了解最佳的解决方案(我是新手)

目前已实施:

->在我的功能服务(如LoginService)中,我注入了有角的HttpClient。然后我简单地打电话给:

return this.httpService.post("/login/", creds).pipe(
      map((data: any) => {
        this.manager = data;
        return this.manager;
      }));

我创建了一个拦截器来更改url:InterceptService实现HttpInterceptor,在其中创建HttpRequest的新实例并使用environment.host自定义request.url。我还需要拦截器为身份验证添加标头(仍未完全实现)

const httpRequest = new HttpRequest(<any>request.method, environment.host + request.url, request.body);
    request = Object.assign(request, httpRequest);

    const headers = new HttpHeaders({
      'Authorization': 'Bearer token 123',
      'Content-Type': 'application/json'
    });

问题:

1)可行,我的所有请求都可以在拦截器中进行更改,但这在我的初看起来并不像最佳实践。我不喜欢创建一个新的HeepRequest来执行此操作(我这样做是为了使其保持不变,我想这是正确的方法)。您觉得这看起来不错吗?

2)将身份验证添加到拦截器的标头中如何?可以吗 我检查过的大多数参考资料都这样做了

其他解决方案:

1)我看到了一些示例,其中HttpClientService扩展了Http,并且每个方法(例如get和post)在调用超级方法之前都编辑了url和标头。但是我相信这不是Angular 6,并且可能不是可取的

2)我还可以创建一个通过注入接收有角HttpClient(角6 HttpClientModule)实例的服务,并且可以实现get或post之类的方法。

法比奥·卡瓦略(Fabio Carvalho)

好吧,由于我没有得到任何答案,所以我将添加我的解决方案。我相信这是根据我的研究得出的最佳解决方案。

我使用拦截器向标头添加信息,例如令牌承载身份验证。

import { Injectable } from '@angular/core';
import {
  HttpEvent,
  HttpInterceptor,
  HttpHandler,
  HttpRequest,
  HttpResponse,
  HttpHeaders,
  HttpErrorResponse
} from '@angular/common/http'
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
import { environment } from "../../../environments/environment";
import { Router } from "@angular/router";

export class HttpClientInterceptor implements HttpInterceptor {

  constructor(private router: Router) { }

  // intercept request to add information to the headers such as the token
  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

    //I decided to remove this logic from the interceptor to add the host url on the HttpClientService I created
    //const httpRequest = new HttpRequest(<any>request.method, environment.host + request.url, request.body);
    //request = Object.assign(request, httpRequest);

    var token = localStorage.getItem("bearerToken");

    if (token) {
      const newReq = request.clone(
        {
          headers: request.headers.set('Authorization',
            'Bearer ' + token)
        });

      return next.handle(newReq).pipe(
        tap(event => {
          if (event instanceof HttpResponse) {
            console.log("Interceptor - HttpResponse = " + event.status); // http response status code
          }
        }, error => {
          // http response status code
          if (error instanceof HttpErrorResponse) {
            console.log("----response----");
            console.error("status code:");
            console.error(error.status);
            console.error(error.message);
            console.log("--- end of response---");

            if (error.status === 401 || error.status === 403) //check if the token expired and redirect to login
              this.router.navigate(['login']);
          }
        })
      )
    }
    else {
      return next.handle(request);
    }
  };

为了更改URL,我在文件http-client.service.ts上创建了一个服务,并从environment.ts获取了主机URL。

import { Injectable } from "@angular/core";
import { HttpClient } from '@angular/common/http';
import { Observable } from "rxjs";
import { environment } from "../../../environments/environment";

@Injectable({ providedIn:'root' })
export class HttpClientService {
  constructor(private http: HttpClient) { }

  get(url: string, options?: any): Observable<ArrayBuffer> {
    url = this.updateUrl(url);
    return this.http.get(url, options);
  }

  post(url: string, body: string, options?: any): Observable<ArrayBuffer> {
    url = this.updateUrl(url);
    return this.http.post(url, body, options);
  }

  put(url: string, body: string, options?: any): Observable<ArrayBuffer> {
    url = this.updateUrl(url);
    return this.http.put(url, body, options);
  }

  delete(url: string, options?: any): Observable<ArrayBuffer> {
    url = this.updateUrl(url);
    return this.http.delete(url,options);
  }

  private updateUrl(req: string) {
    return environment.host + req;
  }
}

如我所说,我相信这是最好的方法,但随时可以在我的问题/答案中添加信息。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章