Nestjs的Http模块

Nestjs的HttpModule模块打包了Axios并且暴露出HttpService接口,HttpService将Axios数据转换为Obervable并返回。比如,HttpService的Post方法在Nestjs源码中是这样写的。

  1. post<T = any>(
  2. url: string,
  3. data?: any,
  4. config?: AxiosRequestConfig,
  5. ): Observable<AxiosResponse<T>> {
  6. return defer(() => this.instance.post(url, data, config));
  7. }

默认情况下,HttpService发送的是JSON风格的请求,但是我们难免要和一些x-www-form-urlencoded风格的API打交道(我是在使用墨迹天气的API时遇到这个坑的)。因为Nestjs仅仅是对Axios进行了封装,因此要到Axios中找答案。

Axios官方说明

Axois官方文档中对使用x-www-form-urlencoded format风格针对浏览器和node环境分别做了如下说明。

  • 浏览器环境

    • 在浏览器中,可以使用URLSearchParamsAPI接口。需要注意的是并不是所有浏览器都支持URLSearchParams,所以可能需要polyfill一下。

      1. const params = new URLSearchParams();
      2. params.append('param1', 'value1');
      3. params.append('param2', 'value2');
      4. axios.post('/foo', params);
    • 在浏览器中也可以使用qs

      1. const qs = require('qs');
      2. axios.post('/foo', qs.stringify({ 'bar': 123 }));
    • 或者使用ES6风格的qs.

      1. //这是官方文档的写法,但是我在nestjs中用import会报找不到模块的错误,需要改成
      2. //import * as qs from 'qs'
      3. //不确定浏览器中是否可以正常使用
      4. import qs from 'qs';
      5. const data = { 'bar': 123 };
      6. const options = {
      7. method: 'POST',
      8. headers: { 'content-type': 'application/x-www-form-urlencoded' },
      9. data: qs.stringify(data),
      10. url,
      11. };
      12. axios(options);
  • nodejs环境
    在nodejs中,可以使用querystring或者qs模块,但是早期版本的querystring存在一些问题,因此官方推荐使用qs模块。

    1. //官方文档,未做验证
    2. const querystring = require('querystring');
    3. axios.post('http://something.com/', querystring.stringify({ foo: 'bar' }));

NestJs中的使用

按照Axios官方文档的推荐,使用qs库,由于qs在axios中封装,而Nestjs封装了Axois,因此不需要额外安装Axios或者qs就能直接使用。以墨迹天气的API接口为例,token和APPCODE需要换成相应内容即可正常使用。

  1. import { Injectable, HttpService, Header } from '@nestjs/common';
  2. import { map } from 'rxjs/operators';
  3. import * as qs from 'qs';
  4. @Injectable()
  5. export class WeatherService {
  6. constructor(private httpService: HttpService) {}
  7. getWeatherId(id) {
  8. const data = { cityId: id,token:**************** };
  9. return this.httpService
  10. .post(
  11. 'http://aliv18.data.moji.com/whapi/json/alicityweather/forecast15days',
  12. qs.stringify(data),
  13. {
  14. headers: {
  15. 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',
  16. Authorization: 'APPCODE *******************',
  17. },
  18. },
  19. )
  20. .pipe(map(response => response.data));
  21. // return this.httpService(options).pipe(
  22. // map(response=>response.data)
  23. // );
  24. }