Skip to content

1.官方HttpClientModule模块

Angular5.x 以后 get、post 和和服务器交互使用的是 HttpClientModule 模块。

1.基本引入

在 app.module.ts 中引入 HttpClientModule 并注入

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

注册这个依赖的模块

js
imports: [
    BrowserModule,
    HttpClientModule
]

2.基本使用

1、get 请求数据

在用到的地方引入 HttpClient 并在构造函数声明 HttpClient

js
import {HttpClient} from "@angular/common/http";

constructor(public http:HttpClient) { }
js
var api = "http://a.itying.com/api/productlist";
this.http.get(api).subscribe(response => {
	console.log(response);
});

//或者:
var api = "http://a.itying.com/api/productlist?id=" + id;
this.http.get(api).subscribe(response => {
	console.log(response);
});

2、post 提交数据

在用到的地方引入 HttpClient、HttpHeaders 并在构造函数声明 HttpClient

js
import {HttpClient,HttpHeaders} from "@angular/common/http";

constructor(public http:HttpClient) { }
js
const httpOptions = {
	headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};
var api = "http://127.0.0.1:3000/doLogin";
this.http.post(api,{username:'张三',age:'20'},httpOptions).subscribe(response => {
	console.log(response);
});

3、jsonp 请求数据

1、在 app.module.ts 中引入 HttpClientModule、HttpClientJsonpModule 并注入

js
import {HttpClientModule, HttpClientJsonpModule} from '@angular/common/http';
js
imports: [
    BrowserModule,
    HttpClientModule,
    HttpClientJsonpModule
]

2、在用到的地方引入 HttpClient 并在构造函数声明

js
import {HttpClient} from "@angular/common/http";

constructor(public http:HttpClient) { }

3、jsonp 请求数据

js
var api = "http://a.itying.com/api/productlist";
this.http.jsonp(api,'callback').subscribe(response => {
	console.log(response);
});

示例:

因为jsonp的原理是调用回调函数从而返回数据,所以最后要拼接一个参数,一般是callback或者cb

jsonp默认是不跨域的!

js
getJsonpData(){
    // jsonp请求 服务器必须得支持jsonp
    /*
        http://a.itying.com/api/productlist?callback=xxx
        http://a.itying.com/api/productlist?cb=xxx
    */

    let api="http://a.itying.com/api/productlist";
    this.http.jsonp(api,'callback').subscribe((response)=>{ //第二个参数,就是我们要拼接的参数名字,callback或者cb
      console.log(response);
    })
}

3.Promise封装HttpClientModule

ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root',
})
export class CommonService {
  public domain: string = 'http://a.itying.com/';
  constructor(public http: HttpClient) {}

  /*
    api/productlist

    http://a.itying.com/api/productlist
  */

  get(api: string) {
    return new Promise((resolve, reject) => {
      this.http.get(this.domain + api).subscribe((response) => {
        resolve(response);
      });
    });
  }
}

4.Rxjs封装HttpClientModule

ts
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable, Subject, throwError } from 'rxjs';
import { catchError, takeUntil, timeout } from 'rxjs/operators';

type Method = 'GET' | 'POST' | 'DELETE' | 'PUT';

/**
 * 统一与后端交互的 httpservice 服务, 作用有以下几点:
 * 1.便于设置统一的超时时间
 * 2.取消pending状态的http请求
 */
@Injectable({
    providedIn: 'root',
})
export class HttpService {
    private cancel$ = new Subject<any>();
    constructor(private http: HttpClient) {}
    get cancelPending() {
        return this.cancel$;
    }

    request(method: Method, url: string, params?: any, body?: any, option?: any): Observable<any> { //添加一些公共配置信息
        const options = {
            params,
            body,
            ...option,
        };
        const timeouts = 30 * 60 * 1000;
        return this.http.request(method, url, options).pipe(
            takeUntil(this.cancel$),
            timeout(timeouts),
            catchError((error) => throwError(error)),
        );
    }

    requestDown(method: Method, url: string, responseType, params?: any, body?: any, option?: any): Observable<any> {
        const options = {
            params,
            body,
            responseType: responseType,
            ...option,
        };
        const timeouts = 30 * 60 * 1000;
        return this.http.request(method, url, options).pipe(
            takeUntil(this.cancel$),
            timeout(timeouts),
            catchError((error) => throwError(error)),
        );
    }

    // 下载报告
    getDownload(url: string, params?: any, options?: any): Observable<any> {
        return this.requestDown('GET', url, 'blob', params, {}, options);
    }

    get(url: string, params?: any, options?: any): Observable<any> { //精分请求类别
        return this.request('GET', url, params, {}, options);
    }

    post(url: string, params?: any, options?: any): Observable<any> {
        return this.request('POST', url, {}, params, options);
    }

    put(url: string, params?: any, options?: any): Observable<any> {
        return this.request('PUT', url, params, options);
    }

    delete(url: string, params?: any, options?: any): Observable<any> {
        return this.request('DELETE', url, params, options);
    }
}
js
.pipe(
    takeUntil(this.cancel$),
    timeout(timeouts),
    catchError((error) => throwError(error)),
)

这部分什么意思?

这部分代码是使用RxJS中的管道操作符来对Observable进行处理。让我们逐个解释这些操作符的含义:

  1. takeUntil(this.cancel$):
    • takeUntil是一个RxJS操作符,它会订阅源Observable,然后监视一个"notifier" Observable(这里是this.cancel$,一个Subject)。
    • 当"notifier" Observable(this.cancel$)发出值时,takeUntil会终止源Observable的订阅,停止接收数据并完成Observable。
  2. timeout(timeouts):
    • timeout是另一个RxJS操作符,它用于设定Observable的超时时间。
    • 如果源Observable在指定的超时时间内未发出任何数据,则会产生一个错误并终止Observable。
  3. catchError((error) => throwError(error)):
    • catchError是RxJS中的操作符,用于捕获Observable中的错误,并返回一个新的Observable(相当于observer.error方法的返回)。
    • 在这里,它捕获任何发生的错误,并将错误作为参数传递给throwError,该操作符会创建一个新的Observable,该Observable会立即产生一个错误。

综合起来,这个管道操作符的作用是:

  • 通过takeUntil(this.cancel$)来监听一个"notifier" Observable(this.cancel$),一旦this.cancel$发出值,就会终止源Observable的订阅,从而取消HTTP请求。
  • 通过timeout(timeouts)来设置源Observable的超时时间,以避免请求无限期等待。
  • 通过catchError((error) => throwError(error))捕获任何可能发生的错误,并将其抛出为一个新的Observable。

这些操作符一起确保了HTTP请求的控制,包括取消和超时处理,以及错误的捕获和传播。

2.第三方axios库与封装

js
import axios from 'axios';

axios.get('/user?ID=12345')
.then(function (response) {
    // handle success
    console.log(response);
})
.catch(function (error) {
    // handle error
    console.log(error);
})
.then(function () {
	// always executed
});

封装一个axios的服务

js
import { Injectable } from '@angular/core';
import axios from 'axios';

@Injectable({
  providedIn: 'root'
})
export class HttpserviceService {
    
  constructor() { }
    
  axiosGet(api:string){
     return new Promise((resolve,reject)=>{
        axios.get(api)
          .then(function (response:any) {
            // handle success     
            resolve(response)
          });
    })
  }  
}
js
//官方数据请求模块
import { HttpClient, HttpHeaders } from '@angular/common/http';

//使用服务里面的axios获取数据
import { HttpserviceService } from '../../services/httpservice.service';
constructor(
    public http: HttpClient,
    public httpService: HttpserviceService
) {}
getAxiosData() {
    console.log('axios获取数据');
    let api = 'http://a.itying.com/api/productlist';

    this.httpService.axiosGet(api).then((data) => {
      console.log(data);
    });
}