feat(http): automatically set request Content-Type header based on body type
Implement the ability to provide objects as request body. The following use cases are supported: * raw objects: a JSON payload is created and the content type set to `application/json` * text: the text is used as it is and no content type header is automatically added * URLSearchParams: a form payload is created and the content type set to `application/x-www-form-urlencoded` * FormData: the object is used as it is and no content type header is automatically added * Blob: the object is used as it is and the content type set with the value of its `type` property if any * ArrayBuffer: the object is used as it is and no content type header is automatically added Closes https://github.com/angular/http/issues/69 Closes #7310
This commit is contained in:

committed by
Misko Hevery

parent
e0c83f669e
commit
0f0a8ade7c
@ -1,6 +1,8 @@
|
||||
import {RequestMethod} from './enums';
|
||||
import {RequestArgs} from './interfaces';
|
||||
import {Headers} from './headers';
|
||||
import {ContentType} from './enums';
|
||||
import {URLSearchParams} from './url_search_params';
|
||||
import {normalizeMethodName} from './http_utils';
|
||||
import {isPresent, StringWrapper} from '../src/facade/lang';
|
||||
|
||||
@ -53,8 +55,10 @@ export class Request {
|
||||
headers: Headers;
|
||||
/** Url of the remote resource */
|
||||
url: string;
|
||||
// TODO: support URLSearchParams | FormData | Blob | ArrayBuffer
|
||||
private _body: string;
|
||||
/** Body of the request **/
|
||||
private _body: any;
|
||||
/** Type of the request body **/
|
||||
private contentType: ContentType;
|
||||
constructor(requestOptions: RequestArgs) {
|
||||
// TODO: assert that url is present
|
||||
let url = requestOptions.url;
|
||||
@ -71,6 +75,7 @@ export class Request {
|
||||
}
|
||||
}
|
||||
this._body = requestOptions.body;
|
||||
this.contentType = this.detectContentType();
|
||||
this.method = normalizeMethodName(requestOptions.method);
|
||||
// TODO(jeffbcross): implement behavior
|
||||
// Defaults to 'omit', consistent with browser
|
||||
@ -85,4 +90,82 @@ export class Request {
|
||||
* string.
|
||||
*/
|
||||
text(): string { return isPresent(this._body) ? this._body.toString() : ''; }
|
||||
|
||||
/**
|
||||
* Returns the request's body as JSON string, assuming that body exists. If body is undefined,
|
||||
* return
|
||||
* empty
|
||||
* string.
|
||||
*/
|
||||
json(): string { return isPresent(this._body) ? JSON.stringify(this._body) : ''; }
|
||||
|
||||
/**
|
||||
* Returns the request's body as array buffer, assuming that body exists. If body is undefined,
|
||||
* return
|
||||
* null.
|
||||
*/
|
||||
arrayBuffer(): ArrayBuffer {
|
||||
if (this._body instanceof ArrayBuffer) return <ArrayBuffer>this._body;
|
||||
throw "The request body isn't an array buffer";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the request's body as blob, assuming that body exists. If body is undefined, return
|
||||
* null.
|
||||
*/
|
||||
blob(): Blob {
|
||||
if (this._body instanceof Blob) return <Blob>this._body;
|
||||
if (this._body instanceof ArrayBuffer) return new Blob([this._body]);
|
||||
throw "The request body isn't either a blob or an array buffer";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the content type of request's body based on its type.
|
||||
*/
|
||||
detectContentType() {
|
||||
if (this._body == null) {
|
||||
return ContentType.NONE;
|
||||
} else if (this._body instanceof URLSearchParams) {
|
||||
return ContentType.FORM;
|
||||
} else if (this._body instanceof FormData) {
|
||||
return ContentType.FORM_DATA;
|
||||
} else if (this._body instanceof Blob) {
|
||||
return ContentType.BLOB;
|
||||
} else if (this._body instanceof ArrayBuffer) {
|
||||
return ContentType.ARRAY_BUFFER;
|
||||
} else if (this._body && typeof this._body == 'object') {
|
||||
return ContentType.JSON;
|
||||
} else {
|
||||
return ContentType.TEXT;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the request's body according to its type. If body is undefined, return
|
||||
* null.
|
||||
*/
|
||||
getBody(): any {
|
||||
switch (this.contentType) {
|
||||
case ContentType.JSON:
|
||||
return this.json();
|
||||
case ContentType.FORM:
|
||||
return this.text();
|
||||
case ContentType.FORM_DATA:
|
||||
return this._body;
|
||||
case ContentType.TEXT:
|
||||
return this.text();
|
||||
case ContentType.BLOB:
|
||||
return this.blob();
|
||||
case ContentType.ARRAY_BUFFER:
|
||||
return this.arrayBuffer();
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const noop = function () {};
|
||||
const w = typeof window == 'object' ? window : noop;
|
||||
const FormData = w['FormData'] || noop;
|
||||
const Blob = w['Blob'] || noop;
|
||||
const ArrayBuffer = w['ArrayBuffer'] || noop;
|
||||
|
Reference in New Issue
Block a user