I know there are a lot of questions about this, but I can't get this to work:
I want to upload a file from input to a server in multipart/form-data
I've tried two approaches. First:
headers: { 'Content-Type': undefined },
Which results in e.g. for an image
Content-Type:image/png
while it should be multipart/form-data
and the other:
headers: { 'Content-Type': multipart/form-data },
But this asks for a boundry header, which I believe should not be manually inserted...
What is a clean way to solve this problem? I've read that you can do
$httpProvider.defaults.headers.post['Content-Type'] = 'multipart/form-data; charset=utf-8';
But I don't want all my posts to be multipart/form-data. The default should be JSON
Follow this rules when creating a multipart form: Specify enctype="multipart/form-data" attribute on a form tag. Add a name attribute to a single input type="file" tag. DO NOT add a name attribute to any other input, select or textarea tags.
Take a look at the FormData object: https://developer.mozilla.org/en/docs/Web/API/FormData
this.uploadFileToUrl = function(file, uploadUrl){ var fd = new FormData(); fd.append('file', file); $http.post(uploadUrl, fd, { transformRequest: angular.identity, headers: {'Content-Type': undefined} }) .success(function(){ }) .error(function(){ }); }
Here's an updated answer for Angular 4 & 5. TransformRequest and angular.identity were dropped. I've also included the ability to combine files with JSON data in one request.
Angular 5 Solution:
import {HttpClient} from '@angular/common/http'; uploadFileToUrl(files, restObj, uploadUrl): Promise<any> { // Note that setting a content-type header // for mutlipart forms breaks some built in // request parsers like multer in express. const options = {} as any; // Set any options you like const formData = new FormData(); // Append files to the virtual form. for (const file of files) { formData.append(file.name, file) } // Optional, append other kev:val rest data to the form. Object.keys(restObj).forEach(key => { formData.append(key, restObj[key]); }); // Send it. return this.httpClient.post(uploadUrl, formData, options) .toPromise() .catch((e) => { // handle me }); }
Angular 4 Solution:
// Note that these imports below are deprecated in Angular 5 import {Http, RequestOptions} from '@angular/http'; uploadFileToUrl(files, restObj, uploadUrl): Promise<any> { // Note that setting a content-type header // for mutlipart forms breaks some built in // request parsers like multer in express. const options = new RequestOptions(); const formData = new FormData(); // Append files to the virtual form. for (const file of files) { formData.append(file.name, file) } // Optional, append other kev:val rest data to the form. Object.keys(restObj).forEach(key => { formData.append(key, restObj[key]); }); // Send it. return this.http.post(uploadUrl, formData, options) .toPromise() .catch((e) => { // handle me }); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With