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

3

28

I have a mini app, where I have to post a form data to an endpoint from browser.

This is my post:

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'}
})

Boundaries seems to be added by formData to the parameter, however, I cannot get it to send in the header, how should I done?

Wotton answered 31/10, 2016 at 22:21 Comment(1)
You are missing closing quote at 'multipart/form-dataDropsonde
W
61

Well, seems that the headers ContentType should be undefined, in order to add the correct boundaries

Wotton answered 1/11, 2016 at 14:36 Comment(0)
R
6

The correct way was to not set 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'}
})

Other headers (like Authorization are fine). Here is an Example:

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);
}

Further adding Pablo's answer.

When http request body has a FormData type, angular will defer Content-Type header assignment to browser. detectContentTypeHeader() will return null on FormData request body and angular won`t set request header.

This was on @angular/commons/http/src/xhr.ts module.

  // 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);
    }
  }

Content-Type detection based on request body:

  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;
  }

Source:

Reticular answered 2/11, 2020 at 22:3 Comment(0)
G
6

If anyone else is struggling with this... If you are submitting FormDate then the browser should be setting the content-type for you. To get this working i just set the enctype header to for 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 })

I also had a HttpInterceptor which was setting the content-type so only set this when the enctype was not set

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

I hope this helps

Gelatinous answered 5/7, 2022 at 16:49 Comment(1)
Thank you very much for your tip!! I was trying to solve a problem for 3 days and I found the reason because of your comment.Plausive

© 2022 - 2024 — McMap. All rights reserved.