angular: Angular 2.0.0 generates invalid Content-Type header for multipart/form-data requests if a default Content-Type header is configured
I’m submitting a … (check one with “x”)
[X] bug report => search github for a similar issue or PR before submitting
[ ] feature request
[ ] support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
Current behavior
If defaultOptions with header Content-Type is set for http, firing a post request with a FormData body and with header Content-Type null or “” leads to the generation of a corrupt Content-Type header.
The Content-Header includes a comma: content-type:, multipart/form-data; boundary=----WebKitFormBoundarylBX4sMHGfDQcsyPM
.
Expected behavior Passing an empty Content-Type header triggers angular’s multipart/form-data routines if the body is a FormData object. Without the defaultOptions, the Content-Type header generation works correctly. The Content-Type header generation should not insert a comma if the header Content-Type is set in the http defaultOptions.
Reproduction of the problem See https://github.com/Nick-Triller/angular2-typescript-webpack
Relevant files:
- app/app.component.ts
- app/app.module.ts
- app/http-interceptor.ts
app.module.ts:
import {NgModule} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {HttpModule, RequestOptions, XHRBackend, Http} from '@angular/http';
import {AppComponent} from './app.component';
import {HttpInterceptor} from "./http-interceptor";
@NgModule({
imports: [
BrowserModule,
HttpModule
],
declarations: [
AppComponent
],
providers: [
// HttpInterceptor
{
provide: Http,
useFactory:
(xhrBackend: XHRBackend, requestOptions: RequestOptions) =>
new HttpInterceptor(xhrBackend, requestOptions),
deps: [XHRBackend, RequestOptions]
}
],
bootstrap: [
AppComponent
]
})
export class AppModule {}
app.component.ts:
/// <reference path="../typings/index.d.ts" />
import {Component} from '@angular/core';
import {Http, RequestOptionsArgs, RequestOptions, Headers} from "@angular/http";
@Component({
selector: 'my-app',
template: `
<input type="file" (change)="filePicked($event)" style="width: 100%">
<button (click)="reproduceBug()">Reproduce bug</button>
`
})
export class AppComponent {
file: File;
constructor(private http: Http) {
}
reproduceBug() {
const url = "url";
let fileReader: FileReader = new FileReader();
let body = new FormData();
fileReader.addEventListener("load", $event => {
body.append("file", fileReader.result);
let options: RequestOptionsArgs = new RequestOptions();
options.headers = new Headers();
options.headers.append("Content-Type", "");
return this.http.post(url, body, options)
.toPromise();
});
// async
fileReader.readAsBinaryString(this.file);
}
filePicked($event) {
this.file = $event.target.files[0];
}
}
http-interceptor.ts
import {ConnectionBackend, Http, Request, RequestOptionsArgs, Response, RequestOptions, Headers} from "@angular/http";
import {Injectable} from "@angular/core";
import "./rxjs-extensions";
import {Observable} from "rxjs/Observable";
/**
* Sets RequestOptions
*/
@Injectable()
export class HttpInterceptor extends Http {
constructor(backend: ConnectionBackend, defaultOptions: RequestOptions) {
super(backend, defaultOptions);
// defaultOptions get merged into other options that are passed into request functions
defaultOptions.headers = new Headers();
defaultOptions.headers.append('Content-Type', 'application/json');
}
}
What is the motivation / use case for changing the behavior? It should be possible to set default Content-Type header and still send multipart/form-data requests.
Please tell us about your environment: Windows 7, Webstorm IDE
Angular version: Angular 2.0.0
Browser: Tested with Firefox 43.0.1 (NO corrupt header) and with Chrome 53.0.2785.116 m (64-bit) with disabled extensions and plugins (corrupt header).
Language: Typescript 1.8.10
Node (for AoT issues): No AoT compilation
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Reactions: 1
- Comments: 15 (6 by maintainers)
I had the same problem! you MUST delete the content type, like this: request.headers.delete(“Content-Type”);
Plunker: https://plnkr.co/edit/Fzo5uD?p=preview
As stated before, the Bug occurs with Chrome 53.0.2785.116 m (64-bit), but not with Firefox 47.0.1. Other browsers or browser versions were not tested.
To reproduce the bug, open the chrome dev tools network tab, pick a file and click the “reproduce bug” button. Check the content-type header for the mutlipart/form-data request. It starts with a comma.
Edit: Changed plunker link
without
options.headers.append("Content-Type", "");
works as expected https://plnkr.co/edit/ViTp47ecIN9kiBw23VfL?p=preview