在发出POST / PUT请求之前,有必要将数据转换为字符串

时间:2019-11-14 10:24:48

标签: angular http https axios

当我们执行API请求POST / PUT时,我们执行JSON.stringify(body),是否有必要?

默认情况下会在发出请求之前对数据进行字符串化(我知道您可以修改),并且在 Angular 中我们也需要对数据进行字符串化。

与安全相关吗?

2 个答案:

答案 0 :(得分:2)

使用不推荐使用的Http模块,是的,在Angular 4+带有新的HttpClientModule之后,它都是自动的,您不再需要自己调用此函数。有人认为您不需要这样做,但是如果您在Angular 4之前就已经在生产环境中构建了应用程序,则需要遵循旧的规则。

阅读: https://angular.io/guide/deprecations#http

编辑:15/11/2019

如您所见:

https://github.com/angular/angular/blob/master/packages/common/http/src/request.ts

HttpClientModule现在自动执行JSON.stringify(this.body)

这是HttpClientModule处理帖子请求的方式:

constructor(method: 'POST'|'PUT'|'PATCH', url: string, body: T|null, init?: {
    headers?: HttpHeaders,
    reportProgress?: boolean,
    params?: HttpParams,
    responseType?: 'arraybuffer'|'blob'|'json'|'text',
    withCredentials?: boolean,
  }); 

这就是现在HttpClientModule自动执行JSON.Stringify()

的方式
 /**
   * Transform the free-form body into a serialized format suitable for
   * transmission to the server.
   */
  serializeBody(): ArrayBuffer|Blob|FormData|string|null {
    // If no body is present, no need to serialize it.
    if (this.body === null) {
      return null;
    }
    // Check whether the body is already in a serialized form. If so,
    // it can just be returned directly.
    if (isArrayBuffer(this.body) || isBlob(this.body) || isFormData(this.body) ||
        typeof this.body === 'string') {
      return this.body;
    }
    // Check whether the body is an instance of HttpUrlEncodedParams.
    if (this.body instanceof HttpParams) {
      return this.body.toString();
    }
    // Check whether the body is an object or array, and serialize with JSON if so.
    if (typeof this.body === 'object' || typeof this.body === 'boolean' ||
        Array.isArray(this.body)) {
      return JSON.stringify(this.body);
    }
    // Fall back on toString() for everything else.
    return (this.body as any).toString();
  }

现在,期待旧的实现是这样:

 /**
   * Performs a request with `post` http method.
   */
  post(url: string, body: any, options?: RequestOptionsArgs): Observable<Response> {
    return httpRequest(
        this._backend, new Request(mergeOptions(
                           this._defaultOptions.merge(new RequestOptions({body: body})), options,
                           RequestMethod.Post, url)));

但是如果没有serializeBody()方法,则只有一个Blob序列化而不是serializeBody

  /**
    * Returns the request's body as a Blob, assuming that body exists.
    */
  blob(): Blob {
    if (this._body instanceof Blob) {
      return <Blob>this._body;
    }

    if (this._body instanceof ArrayBuffer) {
      return new Blob([this._body]);
    }

    throw new Error('The request body isn\'t either a blob or an array buffer');
  }
}

您需要手动进行序列化的地方,例如docs建议:

create(name: string): Promise<Hero> {
  return this.http
    .post(this.heroesUrl, JSON.stringify({name: name}), {headers: this.headers})
    .toPromise()
    .then(res => res.json().data as Hero)
    .catch(this.handleError);
}

答案 1 :(得分:1)

在发出任何 http请求时,我没有使用JSON.stringify()转换数据。无需将数据转换为JSON.stringify()