Инкапсуляция заметок Angular6 http

Ajax внешний фреймворк

Недавно я нашел время, чтобы изучить Angular 6. Раньше я использовал vue в основном, поэтому я неизбежно хочу инкапсулировать инструменты, предоставляемые Angular 6. Сегодня я в основном буду говорить об этом http-модуле.

Используемая ранее библиотека ajax — это axios, которая может устанавливать baseurl, общедоступные заголовки, фокусироваться на захвате ошибок и т. д. Из-за механизма внедрения зависимостей Angular6 ее нельзя инкапсулировать путем прямого изменения переменных, предоставляемых модулем http, но мы знаем из официальной документации, которую мы можем передатьПерехватчик (HttpInterceptor)для достижения этой функции. Перехватчик может перехватить запрос или ответ, а затем передатьзапрос на перехватЭтого можно добиться, установив baseurl, публичный заголовок иперехватить ответОшибки можно отлавливать централизованно. Без лишних слов, давайте перейдем к коду.

Шаг 1: Подготовка, импорт HttpClientModule

Импортируйте HttpClientModule в app.module.ts, а затем добавьте HttpClientModule в BrowserModule в массиве импорта. Конкретный код:

import { HttpClientModule } from '@angular/common/http';

@NgModule({
  imports: [
    BrowserModule,
    // import HttpClientModule after BrowserModule.
    HttpClientModule,
  ],
  declarations: [
    AppComponent,
  ],
  bootstrap: [ AppComponent ]
})

Шаг 2: Создайте новый файл о перехватчике

Создайте новую папку http-interceptors в папке приложения и создайте в ней два файла: base-interceptor.ts и index.ts. Среди них base-interceptor.ts — это файл-инжектор, используемый для установки перехватчика, а index.ts — поставщик расширенного перехватчика.

### base-interceptor.ts

import { Injectable } from '@angular/core';
import {
  HttpEvent, HttpInterceptor, HttpHandler, HttpRequest,
  HttpErrorResponse
} from '@angular/common/http';
import { throwError } from 'rxjs'
import { catchError, retry } from 'rxjs/operators';

/*设置请求的基地址,方便替换*/
const baseurl = 'http://localhost:8360';

@Injectable()
export class BaseInterceptor implements HttpInterceptor {

  constructor() {}

  intercept(req, next: HttpHandler) {

    let newReq = req.clone({
      url: req.hadBaseurl ? `${req.url}` : `${baseurl}${req.url}`,
    });
    /*此处设置额外的头部,token常用于登陆令牌*/
    if(!req.cancelToken) {
	  /*token数据来源自己设置,我常用localStorage存取相关数据*/
      newReq.headers =
      newReq.headers.set('token', 'my-new-auth-token')
    }

    // send cloned request with header to the next handler.
    return next.handle(newReq)
      .pipe(
        /*失败时重试2次,可自由设置*/
        retry(2),
        /*捕获响应错误,可根据需要自行改写,我偷懒了,直接用的官方的*/
        catchError(this.handleError)
      )
  }
  
  private handleError(error: HttpErrorResponse) {
    if (error.error instanceof ErrorEvent) {
      // A client-side or network error occurred. Handle it accordingly.
      console.error('An error occurred:', error.error.message);
    } else {
      // The backend returned an unsuccessful response code.
      // The response body may contain clues as to what went wrong,
      console.error(
        `Backend returned code ${error.status}, ` +
        `body was: ${error.error}`);
    }
    // return an observable with a user-facing error message
    return throwError(
      'Something bad happened; please try again later.');
  };
}


### index.ts

import { HTTP_INTERCEPTORS } from '@angular/common/http';

import { BaseInterceptor } from './base-interceptor';

/** Http interceptor providers in outside-in order */
export const httpInterceptorProviders = [
  { provide: HTTP_INTERCEPTORS, useClass: BaseInterceptor, multi: true },

];

/*
Copyright 2017-2018 Google Inc. All Rights Reserved.
Use of this source code is governed by an MIT-style license that
can be found in the LICENSE file at http://angular.io/license
*/

Модифицировано клонированиемreqОбъект может перехватить запрос, а результат операции **next.handle(newReq)** может перехватить ответ. Если вам нужно изменить его, его можно напрямую расширитьbase-interceptor.tsЛибо обратиться к файлу base-interceptor.ts для создания другого файла, затем корректно внедрить перехватчик в index.ts и добавить его вhttpInterceptorProvidersв массиве.

Шаг 3: Зарегистрируйте провайдера

Добавьте следующий код в app.module.ts:

import { httpInterceptorProviders } from './http-interceptors/index'

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule
  ],
  providers: [
    httpInterceptorProviders
  ],
  bootstrap: [AppComponent]
})

Четвертый шаг, извлечь baseurl

Чтобы облегчить модификацию baseurl в фоновом режиме, мы можем извлечь baseurl как глобальную переменную и установить ее в index.html,

# index.html 增加
<script>
  window.baseurl = "http://localhost:8360"
</script>

# base-interceptor.ts 修改
const baseurl = window.baseurl;

Таким образом, если вы хотите изменить фон, вам нужно только изменить переменные в index.html без повторной компиляции (спасибо_Johnнапоминание). Кроме того, такие переменные, которые могут быть изменены позже, рекомендуется размещать непосредственно в index.html, т.к.тайникПричина, если она введена в файл js, файл не может бытьобновлен вовремяИли нужно каждый раз менять имя файла, что доставит лишние хлопоты.

На данный момент инкапсуляция http модуля Angular6 в основном завершена.При необходимости вы можете расширить его самостоятельно.Можете обратиться ко второму шагу. Если вы не поняли после прочтения или я написал что-то не так, пожалуйста, оставьте комментарий ниже.