如何在multipart/form-data - Angular中获取或设置边界

FormData how to get or set boundary in multipart/form-data - Angular

本文关键字:获取 设置 边界 Angular multipart form-data      更新时间:2023-09-26

我有一个小应用程序,在那里我必须从浏览器发送表单数据到端点。

这是我的帖子:

var formData = new FormData();
formData.append('blobImage', blob, 'imagem' + (new Date()).getTime());
return $http({
  method: 'POST',
  url: api + '/url',
  data: formData,
  headers: {'Content-Type': 'multipart/form-data'}
})

边界似乎是由formData添加到参数,但是,我不能让它发送在头部,我该怎么做?

嗯,似乎标题的ContentType应该是未定义的,以便添加正确的边界

正确的方法是设置Content-Type header

var formData = new FormData();
formData.append('blobImage', blob, 'imagem' + (new Date()).getTime());
return $http({
  method: 'POST',
  url: api + '/url',
  data: formData,
  // headers: {'Content-Type': 'multipart/form-data'}
})

其他标头(如Authorization)。下面是一个例子:

import { http } from '@angular/common/http'
function sendPostData(form: FormData) {
  const url = `https://post-url-example.com/submit`;
  const options = {
    headers: new HttpHeaders({
      Authorization: `Bearer auth-token`
    })
  };
  return http.post(url, form, options);
}

进一步添加Pablo的答案。

当http请求体是FormData类型时,angular会将Content-Type头分配给浏览器。detectContentTypeHeader()会在FormData的请求体上返回null, angular不会设置请求头。

这是@angular/commons/http/src/xhr.ts模块。

  // Auto-detect the Content-Type header if one isn't present already.
  if (!req.headers.has('Content-Type')) {
    const detectedType = req.detectContentTypeHeader();
    // Sometimes Content-Type detection fails.
    if (detectedType !== null) {
      xhr.setRequestHeader('Content-Type', detectedType);
    }
  }

基于请求正文的内容类型检测:

  detectContentTypeHeader(): string|null {
    // An empty body has no content type.
    if (this.body === null) {
      return null;
    }
    // FormData bodies rely on the browser's content type assignment.
    if (isFormData(this.body)) {
      return null;
    }
    // Blobs usually have their own content type. If it doesn't, then
    // no type can be inferred.
    if (isBlob(this.body)) {
      return this.body.type || null;
    }
    // Array buffers have unknown contents and thus no type can be inferred.
    if (isArrayBuffer(this.body)) {
      return null;
    }
    // Technically, strings could be a form of JSON data, but it's safe enough
    // to assume they're plain strings.
    if (typeof this.body === 'string') {
      return 'text/plain';
    }
    // `HttpUrlEncodedParams` has its own content-type.
    if (this.body instanceof HttpParams) {
      return 'application/x-www-form-urlencoded;charset=UTF-8';
    }
    // Arrays, objects, and numbers will be encoded as JSON.
    if (typeof this.body === 'object' || typeof this.body === 'number' ||
        Array.isArray(this.body)) {
      return 'application/json';
    }
    // No type could be inferred.
    return null;
  }
源:

  • @angular/共同/http/src/xhr.ts
  • @angular/共同/http/src/request.ts

如果有人正在努力…如果你提交的是FormDate,那么浏览器应该会为你设置内容类型。为了得到这个工作,我只是将enctype头设置为multipart/form-data

const formData = new FormData();
formData.append('file', file);
let headers = new HttpHeaders();
headers = headers.append('enctype', 'multipart/form-data');
return this.http.post(path, formData, { headers: headers })

我也有一个HttpInterceptor设置内容类型所以只有当enctype没有设置时才设置这个

if (!req.headers.has('enctype')) {
headersConfig['Content-Type'] = 'application/json';
}

希望对大家有所帮助