'Send multipart/form-data files with angular using $http
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
Solution 1:[1]
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(){
});
}
Solution 2:[2]
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
});
}
Solution 3:[3]
In Angular 6, you can do this:
In your service file:
function_name(data) {
const url = `the_URL`;
let input = new FormData();
input.append('url', data); // "url" as the key and "data" as value
return this.http.post(url, input).pipe(map((resp: any) => resp));
}
In component.ts file: in any function say xyz,
xyz(){
this.Your_service_alias.function_name(data).subscribe(d => { // "data" can be your file or image in base64 or other encoding
console.log(d);
});
}
Solution 4:[4]
In angular 9, Before tried 'Content-Type': undefined, but it is not worked for me then I tried the below code and It works like charms for a file object
const request = this.http.post(url, data, {
headers: {
'Content-Type': 'file'
},
});
Solution 5:[5]
Do not Set, Reset or Update the built in FormData's Content-Type. It will be solved. In Angular 7 it works.
Though there was an Auth-Interceptor But I did not let it set, change or reset my Content-Type header of my post request. Let it be what it is and the problem is solved.
Here is my auth interceptor image where I by passed my request
Solution 6:[6]
In Angular 13 (~13.0.0) isn't need to specify Content-Type of request.
some.service.ts:
public sendFiles(data: any): Observable<any> {
const formData = new FormData();
data.files.forEach((file: File) => {
formData.append('files', file);
});
const url: string = <YOUR_API_URL>;
return this.http.post<any>(url, formData);
}
- Set Content-Type field to the following values ??will result in error:
- 'file'
- undefined (can't with strict mode active)
- 'multipart/form-data'
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | jstuartmilne |
| Solution 2 | |
| Solution 3 | Abhishek Gupta |
| Solution 4 | Suraj Rao |
| Solution 5 | |
| Solution 6 |
