IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> angular Http客户端 -> 正文阅读

[JavaScript知识库]angular Http客户端

前端开发,axios是标配的http请求发起libary, 采用的是Promise的方式。然后,Angular中采用的是另外一种形式Observable 观察订阅模式。Angular默认推荐采用内置的HttpClient,也就是 @angular/common/http 中的 HttpClient 服务类,用于与服务器进行通讯。

HTTP 客户端服务提供了以下主要功能。

  • 请求类型化响应对象的能力。

  • 简化的错误处理。

  • 各种特性的可测试性。

  • 请求和响应的拦截机制。

模块引入

要想使用 HttpClient,就要先导入 Angular 的 HttpClientModule。大多数应用都会在根模块 AppModule 中导入它。如下:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http';

@NgModule({
  imports: [
    BrowserModule,
    // import
    HttpClientModule,
  ],
  declarations: [
    AppComponent,
  ],
  bootstrap: [ AppComponent ]
})
export class AppModule {}

然后,你可以把 HttpClient 服务注入成一个应用类的依赖项:ajax.service.ts

/**** ajax.service.ts ****/
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable()
export class ConfigService {
  constructor(private http: HttpClient) { }
  // 对 httpclient 进行封装 get、post、put、delete
}

get 请求数据

使用 HttpClient.get() 方法从服务器获取数据。该异步方法会发送一个 HTTP 请求,并返回一个 Observable可观察对象,它会在收到响应时发出所请求到的数据。

get() 方法有两个参数。要获取的端点 URL,以及一个可以用来配置请求的options选项对象。

options: {
    headers?: HttpHeaders | {[header: string]: string | string[]},	// 配置请求头
    observe?: 'body' | 'events' | 'response',	// 指定要返回的响应内容,默认值 body
    params?: HttpParams|{[param: string]: string | number | boolean | ReadonlyArray<string | number | boolean>},	// 附加在 url 字符串后面作为 get 请求参数
    reportProgress?: boolean,	// 选项可以在传输大量数据时监听进度
    responseType?: 'arraybuffer'|'blob'|'json'|'text',	// 指定返回数据的格式,默认值 json
    withCredentials?: boolean,	// 是否携带 cookie
  }

演示get请求数据

this.http.get('/api/data', {
	params: new HttpParams().set('page', "1").set('limit', "50"),
	headers: new HttpHeaders({'Authorization': 'my-auth-token'})
}).subscribe((data: any) => console.log(data));

post 请求

this.http.post(
	'/api/data',	// url 地址
	{ "params1": 1, "params2": 2 },
	{ headers: new HttpHeaders({'Authorization': 'my-auth-token'}) }	// 配置请求头,一般在请求拦截器配置请求头
).subscribe(
	res => { console.log("POST call successful value returned in body", res); },
	error => { console.log("POST call in error", error); },
 	() => { console.log("The POST observable is now completed.");
);

put 请求

this.http.put(
	'/api/data',	// url 地址
	{ "params1": 1, "params2": 2 },	// body 请求体参数
	{ headers: new HttpHeaders({'Authorization': 'my-auth-token'}) }	// 配置请求头,一般在请求拦截器配置请求头
).subscribe(
	res => { console.log("POST call successful value returned in body", res); },
	error => { console.log("POST call in error", error); },
 	() => { console.log("The POST observable is now completed.");
);

delete 请求

const url = `${this.url}/${id}`		// `/api/data/22`
this.http.delete(
	url, 
	{ headers: new HttpHeaders({'Authorization': 'my-auth-token' } 
).subscribe(
	res => { console.log("POST call successful value returned in body", res); },
	error => { console.log("POST call in error", error); },
 	() => { console.log("The POST observable is now completed.");
);

JSONP 请求

当服务器不支持 CORS 协议时,应用程序可以使用 HttpClient 跨域发出 JSONP 请求。

this.http.jsonp('/api/handle', 'callback').pipe(
      catchError(this.handleError('searchHeroes', []))
).subscribe(
	res => { console.log("POST call successful value returned in body", res); },
	error => { console.log("POST call in error", error); },
 	() => { console.log("The POST observable is now completed.");
);

请求错误处理

如果请求在服务器上失败了,那么HttpClient 就会返回一个错误对象(HttpErrorResponse)而不是一个成功的响应对象(HttpResponse)。
如下:以get·请求为例,在ajax.service.ts中添加错误处理器

// 1、添加错误处理器
private handleError(error: HttpErrorResponse) {
	if(error instanceof HttpErrorResponse) {
		if (error.status === 0) {
			console.error('An error occurred:', error.error);
		} else {
		    console.error(`Backend returned code ${error.status}, ` + `body was: ${error.error}`);
		}
		return throwError('Something bad happened; please try again later.');
	}
}
this.http.get(this.configUrl).pipe(
	// 3、有时候,错误只是临时性的,只要重试就可能会自动消失,因此可以先重试发送请求
	retry(3),	// 如果发生错误的话,重试发送请求。试 3 次
	// 2、当发生错误时,使用一个管道把 HttpClient.get() 调用返回的所有 Observable 发送给错误处理器
	catchError(this.handleError)	
).subscribe(res => console.log(res))

处理错误请求一般在拦截器统一处理

拦截请求和响应

在上面的请求中,每一个请求都要单独为请求头加入认证字段,增加代码冗余,可以直接在请求拦截器中配置好请求头,而不用每次请求都单独配置。

要实现拦截器,就要实现一个实现了 HttpInterceptor 接口中的 intercept()方法的类。如下:default.interceptor.ts

/**** default.interceptor.ts ****/
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest } from '@angular/common/http';
import { Observable } from 'rxjs';

export class DefaultInterceptor implements HttpInterceptor {
  // 拦截器,实现 HttpInterceptor 接口的 intercept 方法
  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
  	console.log(req)	// http请求对象
  	// 使用场景 1:拦截请求,修改请求参数
  	// 1.1、获取token
    const authToken = localStorage.getItem("token")
    // 1.2、重新克隆一份请求数据,并更新认证字段,设置默认请求头
    const authReq = req.clone({
      headers: req.headers.set('Authorization', authToken)
    });
    // const authReq = req.clone({ setHeaders: { Authorization: authToken } });	// 设置请求头部快捷方式
  	console.log(authReq)
  	// 1.3、将处理好的数据发送给下一个拦截器
    return next.handle(authReq);
  }
}

intercept要求我们返回一个Observable对象供组件订阅使用,该方法有两个形参:

  • req:HttpRequest类型,这个是我们http请求对象;
  • next:HttpHandler类型,next 对象表示拦截器链表中的下一个拦截器,它提供了handle()方法,可以把HTTP请求转换成HttpEvent类型的Observable, 这个链表中的最后一个 next 对象就是 HttpClient 的后端返回的response

声明之后我们需要在app.module.ts根模块注入这个拦截器。如下:

/**** app.module.ts ****/
import { DefaultInterceptor } from '@core/net/default.interceptor';
import { HttpClient, HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';
@NgModule({
  imports: [
    BrowserModule,
    HttpClientModule,
    BrowserAnimationsModule,
  ],
  declarations: [
    AppComponent,
  ],
  providers: [
    { provide: HTTP_INTERCEPTORS, useClass: DefaultInterceptor, multi: true }
  ],
  bootstrap: [AppComponent]
})

export class AppModule { }

multi: true 选项。 这个必须的选项会告诉 Angular HTTP_INTERCEPTORS 是一个多重提供者的令牌,表示它会注入一个多值的数组,而不是单一的值。

集中维护拦截器

当声明的拦截器越来越多时不好维护,可以专门建立一个文件夹来维护这些拦截器,并提供一个index.ts文件把所有拦截器封装成一个数组对象然后暴露出来,最后再在app.module.ts中注入这些拦截器,如下:目录结构

在这里插入图片描述

而在index.ts中如下:

/**** index.ts ****/
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { DefaultInterceptor } from './default.interceptor'
import { BloodInterceptor } from './blood.interceptor'
...
// 暴露拦截器数组
export const HttpInterceptorProviders = [
    { provide: HTTP_INTERCEPTORS, useClass: DefaultInterceptor, multi: true },
    { provide: HTTP_INTERCEPTORS, useClass: BloodInterceptor, multi: true },
    ...
]

最后在app.module.ts根模块中注入

/**** app.module.ts ****/
import { HttpInterceptorProviders } from './interceptor/index';
@NgModule({
  imports: [
	...
  ],
  declarations: [
    AppComponent,
  ],
  providers: [
    ...HttpInterceptorProviders,	// 注册
  ],
  bootstrap: [AppComponent]
})

export class AppModule { }

拦截器多了之后,它的执行顺序其实就是export的这个数组的索引下标顺序0,1,2…

捕获响应错误,集中处理

当每一次请求发生错误的时候,我们一般都要进行错误处理,但是每次都对每个单独错误处理很麻烦,可以专门添加一个错误处理拦截器,如下:catchError.injector.ts

/**** catchError.injector.ts ****/
import { HttpInterceptor, HttpRequest, HttpHandler } from '@angular/common/http';
import { catchError, retry } from 'rxjs/operators';

export class CatchErrorInjector implements HttpInterceptor {
	// 错误处理器
	private handleError(error: HttpErrorResponse) {
		if(error instanceof HttpErrorResponse) {
			// 错误处理
		}
	}

  intercept(req: HttpRequest<any>, next: HttpHandler) {
    return next.handle(req).pipe(
      retry(3),
      catchError(err => {
        // 统一处理错误信息,可以使用项目已有的消息组件抛出错误信息,也可以根据请求的错误码类型做更多的处理,
        console.log(err, '后端接口报错');
        this.handleError(err)
      })
    );
  }
}
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-09-19 07:54:08  更:2021-09-19 07:55:30 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 18:50:50-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码