Request Interception in Angular

Get into the habit of writing together! This is the sixth day of my participation in the "Nuggets Daily New Plan · April Update Challenge", click to view the details of the event

In the previous article , Using Api Proxy in Angular , we dealt with the problem of the local joint debugging interface and used the proxy.

Our interfaces are written and processed separately. In actual development projects, there are many interfaces, some of which require login credentials and some do not. If one interface is not handled properly, can we consider intercepting and encapsulating the request?

This article implements it.

Differentiate the environment

We need to intercept services in different environments. When using angular-clito generate a project, it has automatically distinguished the environment, in the app/enviromentsdirectory:

environments                                          
├── environment.prod.ts                  // 生产环境使用的配置
└── environment.ts                       // 开发环境使用的配置
复制代码

We modify the development environment as follows:

// enviroment.ts

export const environment = {
  baseUrl: '',
  production: false
};
复制代码

baseUrlIt is a field added to the front of the request when you make a request, and it points to the address you want to request. I didn't add anything, in fact, it was equivalent to adding http://localhost:4200the content of .

Of course, the content you add here should be adjusted to match the content added on your agent, and readers can think and verify by themselves

add interceptor

We generate a service http-interceptor.service.tsinterceptor service, and we want every request to go through this service.

// http-interceptor.service.ts

import { Injectable } from '@angular/core';
import {
  HttpEvent,
  HttpHandler,
  HttpInterceptor, // 拦截器
  HttpRequest, // 请求
} from '@angular/common/http';

import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';

import { environment } from 'src/environments/environment';

@Injectable({
  providedIn: 'root'
})
export class HttpInterceptorService implements HttpInterceptor {

  constructor() { }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    let secureReq: HttpRequest<any> = req;

    secureReq = secureReq.clone({
      url: environment.baseUrl + req.url
    });

    return next.handle(secureReq).pipe(
      tap(
        (response: any) => {
          // 处理响应的数据
          console.log(response)
        },
        (error: any) => {
          // 处理错误的数据
          console.log(error)
        }
      )
    )
  }
}
复制代码

For the interceptor to take effect, we have app.module.tsto inject it on :

// app.module.ts

import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
// 拦截器服务
import { HttpInterceptorService } from './services/http-interceptor.service';

providers: [
  // 依赖注入
  {
    provide: HTTP_INTERCEPTORS,
    useClass: HttpInterceptorService,
    multi: true,
  }
],
复制代码

verify

So far, we have successfully implemented the interceptor. If you run npm run dev, you will see the following message on the console:

Interceptor-response.png

To verify that content credentials are required to access the content, here I tried using [post] https://jimmyarea.com/api/private/leave/messagethe interface of , and got the following error:

interface-401.png

The backend has already processed this interface and requires credentials to operate, so an error is reported directly 401.

Well, here comes the question. After we log in, how do we need to bring our credentials?

As follows, we modify the content of the interceptor:

let secureReq: HttpRequest<any> = req;
// ...
// 使用 localhost 存储用户凭证,在请求头带上
if (window.localStorage.getItem('ut')) {
  let token = window.localStorage.getItem('ut') || ''
  secureReq = secureReq.clone({
    headers: req.headers.set('token', token)
  });
}

// ...
复制代码

The validity period of this certificate requires readers to judge whether the validity period is valid when entering the system, and then consider localstoragethe reset value, otherwise an error will be reported all the localstoragetime.

【End】✅

Guess you like

Origin juejin.im/post/7083272307930169352