fix(Header): preserve case of the first init, `set()` or `append()` (#12023)
fixes #11624
This commit is contained in:
parent
1cf5f5fa38
commit
ed9c2b6281
|
@ -6,7 +6,7 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {ListWrapper, MapWrapper, StringMapWrapper, isListLikeIterable, iterateListLike} from '../src/facade/collection';
|
import {MapWrapper} from '../src/facade/collection';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Polyfill for [Headers](https://developer.mozilla.org/en-US/docs/Web/API/Headers/Headers), as
|
* Polyfill for [Headers](https://developer.mozilla.org/en-US/docs/Web/API/Headers/Headers), as
|
||||||
|
@ -15,7 +15,7 @@ import {ListWrapper, MapWrapper, StringMapWrapper, isListLikeIterable, iterateLi
|
||||||
* The only known difference between this `Headers` implementation and the spec is the
|
* The only known difference between this `Headers` implementation and the spec is the
|
||||||
* lack of an `entries` method.
|
* lack of an `entries` method.
|
||||||
*
|
*
|
||||||
* ### Example ([live demo](http://plnkr.co/edit/MTdwT6?p=preview))
|
* ### Example
|
||||||
*
|
*
|
||||||
* ```
|
* ```
|
||||||
* import {Headers} from '@angular/http';
|
* import {Headers} from '@angular/http';
|
||||||
|
@ -37,23 +37,31 @@ import {ListWrapper, MapWrapper, StringMapWrapper, isListLikeIterable, iterateLi
|
||||||
* @experimental
|
* @experimental
|
||||||
*/
|
*/
|
||||||
export class Headers {
|
export class Headers {
|
||||||
/** @internal */
|
/** @internal header names are lower case */
|
||||||
_headersMap: Map<string, string[]>;
|
_headers: Map<string, string[]> = new Map();
|
||||||
constructor(headers?: Headers|{[key: string]: any}) {
|
/** @internal map lower case names to actual names */
|
||||||
if (headers instanceof Headers) {
|
_normalizedNames: Map<string, string> = new Map();
|
||||||
this._headersMap = new Map<string, string[]>((<Headers>headers)._headersMap);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._headersMap = new Map<string, string[]>();
|
|
||||||
|
|
||||||
|
// TODO(vicb): any -> string|string[]
|
||||||
|
constructor(headers?: Headers|{[name: string]: any}) {
|
||||||
if (!headers) {
|
if (!headers) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// headers instanceof StringMap
|
if (headers instanceof Headers) {
|
||||||
StringMapWrapper.forEach(headers, (v: any, k: string) => {
|
headers._headers.forEach((value: string[], name: string) => {
|
||||||
this._headersMap.set(normalize(k), isListLikeIterable(v) ? v : [v]);
|
const lcName = name.toLowerCase();
|
||||||
|
this._headers.set(lcName, value);
|
||||||
|
this.mayBeSetNormalizedName(name);
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.keys(headers).forEach((name: string) => {
|
||||||
|
const value = headers[name];
|
||||||
|
const lcName = name.toLowerCase();
|
||||||
|
this._headers.set(lcName, Array.isArray(value) ? value : [value]);
|
||||||
|
this.mayBeSetNormalizedName(name);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,14 +69,14 @@ export class Headers {
|
||||||
* Returns a new Headers instance from the given DOMString of Response Headers
|
* Returns a new Headers instance from the given DOMString of Response Headers
|
||||||
*/
|
*/
|
||||||
static fromResponseHeaderString(headersString: string): Headers {
|
static fromResponseHeaderString(headersString: string): Headers {
|
||||||
let headers = new Headers();
|
const headers = new Headers();
|
||||||
|
|
||||||
headersString.split('\n').forEach(line => {
|
headersString.split('\n').forEach(line => {
|
||||||
const index = line.indexOf(':');
|
const index = line.indexOf(':');
|
||||||
if (index > 0) {
|
if (index > 0) {
|
||||||
const key = line.substring(0, index);
|
const name = line.slice(0, index);
|
||||||
const value = line.substring(index + 1).trim();
|
const value = line.slice(index + 1).trim();
|
||||||
headers.set(key, value);
|
headers.set(name, value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -79,92 +87,94 @@ export class Headers {
|
||||||
* Appends a header to existing list of header values for a given header name.
|
* Appends a header to existing list of header values for a given header name.
|
||||||
*/
|
*/
|
||||||
append(name: string, value: string): void {
|
append(name: string, value: string): void {
|
||||||
name = normalize(name);
|
const values = this.getAll(name);
|
||||||
var mapName = this._headersMap.get(name);
|
this.set(name, values === null ? [value] : [...values, value]);
|
||||||
var list = isListLikeIterable(mapName) ? mapName : [];
|
|
||||||
list.push(value);
|
|
||||||
this._headersMap.set(name, list);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes all header values for the given name.
|
* Deletes all header values for the given name.
|
||||||
*/
|
*/
|
||||||
delete (name: string): void { this._headersMap.delete(normalize(name)); }
|
delete (name: string): void {
|
||||||
|
const lcName = name.toLowerCase();
|
||||||
|
this._normalizedNames.delete(lcName);
|
||||||
|
this._headers.delete(lcName);
|
||||||
|
}
|
||||||
|
|
||||||
forEach(fn: (values: string[], name: string, headers: Map<string, string[]>) => void): void {
|
forEach(fn: (values: string[], name: string, headers: Map<string, string[]>) => void): void {
|
||||||
this._headersMap.forEach(fn);
|
this._headers.forEach(
|
||||||
|
(values, lcName) => fn(values, this._normalizedNames.get(lcName), this._headers));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns first header that matches given name.
|
* Returns first header that matches given name.
|
||||||
*/
|
*/
|
||||||
get(header: string): string { return ListWrapper.first(this._headersMap.get(normalize(header))); }
|
get(name: string): string {
|
||||||
|
const values = this.getAll(name);
|
||||||
|
|
||||||
|
if (values === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return values.length > 0 ? values[0] : null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check for existence of header by given name.
|
* Checks for existence of header by given name.
|
||||||
*/
|
*/
|
||||||
has(header: string): boolean { return this._headersMap.has(normalize(header)); }
|
has(name: string): boolean { return this._headers.has(name.toLowerCase()); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides names of set headers
|
* Returns the names of the headers
|
||||||
*/
|
*/
|
||||||
keys(): string[] { return MapWrapper.keys(this._headersMap); }
|
keys(): string[] { return MapWrapper.values(this._normalizedNames); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets or overrides header value for given name.
|
* Sets or overrides header value for given name.
|
||||||
*/
|
*/
|
||||||
set(header: string, value: string|string[]): void {
|
set(name: string, value: string|string[]): void {
|
||||||
var list: string[] = [];
|
const strValue = Array.isArray(value) ? value.join(',') : value;
|
||||||
|
this._headers.set(name.toLowerCase(), [strValue]);
|
||||||
if (isListLikeIterable(value)) {
|
this.mayBeSetNormalizedName(name);
|
||||||
var pushValue = (<string[]>value).join(',');
|
|
||||||
list.push(pushValue);
|
|
||||||
} else {
|
|
||||||
list.push(<string>value);
|
|
||||||
}
|
|
||||||
|
|
||||||
this._headersMap.set(normalize(header), list);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns values of all headers.
|
* Returns values of all headers.
|
||||||
*/
|
*/
|
||||||
values(): string[][] { return MapWrapper.values(this._headersMap); }
|
values(): string[][] { return MapWrapper.values(this._headers); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns string of all headers.
|
* Returns string of all headers.
|
||||||
*/
|
*/
|
||||||
toJSON(): {[key: string]: any} {
|
// TODO(vicb): returns {[name: string]: string[]}
|
||||||
let serializableHeaders = {};
|
toJSON(): {[name: string]: any} {
|
||||||
this._headersMap.forEach((values: string[], name: string) => {
|
const serialized: {[name: string]: string[]} = {};
|
||||||
let list: any[] /** TODO #9100 */ = [];
|
|
||||||
|
|
||||||
iterateListLike(
|
this._headers.forEach((values: string[], name: string) => {
|
||||||
values, (val: any /** TODO #9100 */) => list = ListWrapper.concat(list, val.split(',')));
|
const split: string[] = [];
|
||||||
|
values.forEach(v => split.push(...v.split(',')));
|
||||||
(serializableHeaders as any /** TODO #9100 */)[normalize(name)] = list;
|
serialized[this._normalizedNames.get(name)] = split;
|
||||||
});
|
});
|
||||||
return serializableHeaders;
|
|
||||||
|
return serialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns list of header values for a given name.
|
* Returns list of header values for a given name.
|
||||||
*/
|
*/
|
||||||
getAll(header: string): string[] {
|
getAll(name: string): string[] {
|
||||||
var headers = this._headersMap.get(normalize(header));
|
return this.has(name) ? this._headers.get(name.toLowerCase()) : null;
|
||||||
return isListLikeIterable(headers) ? headers : [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is not implemented.
|
* This method is not implemented.
|
||||||
*/
|
*/
|
||||||
entries() { throw new Error('"entries" method is not implemented on Headers class'); }
|
entries() { throw new Error('"entries" method is not implemented on Headers class'); }
|
||||||
}
|
|
||||||
|
|
||||||
// "HTTP character sets are identified by case-insensitive tokens"
|
private mayBeSetNormalizedName(name: string): void {
|
||||||
// Spec at https://tools.ietf.org/html/rfc2616
|
const lcName = name.toLowerCase();
|
||||||
// This implementation is same as NodeJS.
|
|
||||||
// see https://nodejs.org/dist/latest-v6.x/docs/api/http.html#http_message_headers
|
if (!this._normalizedNames.has(lcName)) {
|
||||||
function normalize(name: string): string {
|
this._normalizedNames.set(lcName, name);
|
||||||
return name.toLowerCase();
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,22 +6,13 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {beforeEach, describe, expect, it} from '@angular/core/testing/testing_internal';
|
|
||||||
import {Json} from '../src/facade/lang';
|
|
||||||
import {Headers} from '../src/headers';
|
import {Headers} from '../src/headers';
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
describe('Headers', () => {
|
describe('Headers', () => {
|
||||||
|
|
||||||
|
describe('initialization', () => {
|
||||||
it('should conform to spec', () => {
|
it('should conform to spec', () => {
|
||||||
// Examples borrowed from https://developer.mozilla.org/en-US/docs/Web/API/Headers/Headers
|
|
||||||
// Spec at https://fetch.spec.whatwg.org/#dom-headers
|
|
||||||
var firstHeaders = new Headers(); // Currently empty
|
|
||||||
firstHeaders.append('Content-Type', 'image/jpeg');
|
|
||||||
expect(firstHeaders.get('Content-Type')).toBe('image/jpeg');
|
|
||||||
// "HTTP character sets are identified by case-insensitive tokens"
|
|
||||||
// Spec at https://tools.ietf.org/html/rfc2616
|
|
||||||
expect(firstHeaders.get('content-type')).toBe('image/jpeg');
|
|
||||||
expect(firstHeaders.get('content-Type')).toBe('image/jpeg');
|
|
||||||
const httpHeaders = {
|
const httpHeaders = {
|
||||||
'Content-Type': 'image/jpeg',
|
'Content-Type': 'image/jpeg',
|
||||||
'Accept-Charset': 'utf-8',
|
'Accept-Charset': 'utf-8',
|
||||||
|
@ -29,23 +20,22 @@ export function main() {
|
||||||
};
|
};
|
||||||
const secondHeaders = new Headers(httpHeaders);
|
const secondHeaders = new Headers(httpHeaders);
|
||||||
const secondHeadersObj = new Headers(secondHeaders);
|
const secondHeadersObj = new Headers(secondHeaders);
|
||||||
expect(secondHeadersObj.get('Content-Type')).toBe('image/jpeg');
|
expect(secondHeadersObj.get('Content-Type')).toEqual('image/jpeg');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
describe('initialization', () => {
|
|
||||||
it('should merge values in provided dictionary', () => {
|
it('should merge values in provided dictionary', () => {
|
||||||
const headers = new Headers({'foo': 'bar'});
|
const headers = new Headers({'foo': 'bar'});
|
||||||
expect(headers.get('foo')).toBe('bar');
|
expect(headers.get('foo')).toEqual('bar');
|
||||||
expect(headers.getAll('foo')).toEqual(['bar']);
|
expect(headers.getAll('foo')).toEqual(['bar']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not alter the values of a provided header template', () => {
|
it('should not alter the values of a provided header template', () => {
|
||||||
// Spec at https://fetch.spec.whatwg.org/#concept-headers-fill
|
// Spec at https://fetch.spec.whatwg.org/#concept-headers-fill
|
||||||
// test for https://github.com/angular/angular/issues/6845
|
// test for https://github.com/angular/angular/issues/6845
|
||||||
const firstHeaders = new Headers();
|
const firstHeaders = new Headers();
|
||||||
const secondHeaders = new Headers(firstHeaders);
|
const secondHeaders = new Headers(firstHeaders);
|
||||||
secondHeaders.append('Content-Type', 'image/jpeg');
|
secondHeaders.append('Content-Type', 'image/jpeg');
|
||||||
expect(firstHeaders.has('Content-Type')).toBeFalsy();
|
expect(firstHeaders.has('Content-Type')).toEqual(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -53,56 +43,104 @@ export function main() {
|
||||||
describe('.set()', () => {
|
describe('.set()', () => {
|
||||||
it('should clear all values and re-set for the provided key', () => {
|
it('should clear all values and re-set for the provided key', () => {
|
||||||
const headers = new Headers({'foo': 'bar'});
|
const headers = new Headers({'foo': 'bar'});
|
||||||
expect(headers.get('foo')).toBe('bar');
|
expect(headers.get('foo')).toEqual('bar');
|
||||||
expect(headers.getAll('foo')).toEqual(['bar']);
|
|
||||||
headers.set('foo', 'baz');
|
headers.set('foo', 'baz');
|
||||||
expect(headers.get('foo')).toBe('baz');
|
expect(headers.get('foo')).toEqual('baz');
|
||||||
expect(headers.getAll('foo')).toEqual(['baz']);
|
|
||||||
|
headers.set('fOO', 'bat');
|
||||||
|
expect(headers.get('foo')).toEqual('bat');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should preserve the case of the first call', () => {
|
||||||
|
const headers = new Headers();
|
||||||
|
headers.set('fOo', 'baz');
|
||||||
|
headers.set('foo', 'bat');
|
||||||
|
expect(JSON.stringify(headers)).toEqual('{"fOo":["bat"]}');
|
||||||
|
});
|
||||||
|
|
||||||
it('should convert input array to string', () => {
|
it('should convert input array to string', () => {
|
||||||
var headers = new Headers();
|
const headers = new Headers();
|
||||||
var inputArr = ['bar', 'baz'];
|
headers.set('foo', ['bar', 'baz']);
|
||||||
headers.set('foo', inputArr);
|
expect(headers.get('foo')).toEqual('bar,baz');
|
||||||
expect(/bar, ?baz/g.test(headers.get('foo'))).toBe(true);
|
expect(headers.getAll('foo')).toEqual(['bar,baz']);
|
||||||
expect(/bar, ?baz/g.test(headers.getAll('foo')[0])).toBe(true);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('.get()', () => {
|
||||||
|
it('should be case insensitive', () => {
|
||||||
|
const headers = new Headers();
|
||||||
|
headers.set('foo', 'baz');
|
||||||
|
expect(headers.get('foo')).toEqual('baz');
|
||||||
|
expect(headers.get('FOO')).toEqual('baz');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return null if the header is not present', () => {
|
||||||
|
const headers = new Headers({bar: []});
|
||||||
|
expect(headers.get('bar')).toEqual(null);
|
||||||
|
expect(headers.get('foo')).toEqual(null);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('.getAll()', () => {
|
||||||
|
it('should be case insensitive', () => {
|
||||||
|
const headers = new Headers({foo: ['bar', 'baz']});
|
||||||
|
expect(headers.getAll('foo')).toEqual(['bar', 'baz']);
|
||||||
|
expect(headers.getAll('FOO')).toEqual(['bar', 'baz']);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return null if the header is not present', () => {
|
||||||
|
const headers = new Headers();
|
||||||
|
expect(headers.getAll('foo')).toEqual(null);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('.delete', () => {
|
||||||
|
it('should be case insensitive', () => {
|
||||||
|
const headers = new Headers();
|
||||||
|
|
||||||
|
headers.set('foo', 'baz');
|
||||||
|
expect(headers.has('foo')).toEqual(true);
|
||||||
|
headers.delete('foo');
|
||||||
|
expect(headers.has('foo')).toEqual(false);
|
||||||
|
|
||||||
|
headers.set('foo', 'baz');
|
||||||
|
expect(headers.has('foo')).toEqual(true);
|
||||||
|
headers.delete('FOO');
|
||||||
|
expect(headers.has('foo')).toEqual(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('.append', () => {
|
||||||
|
it('should preserve the case of the first call', () => {
|
||||||
|
const headers = new Headers();
|
||||||
|
|
||||||
|
headers.append('FOO', 'bar');
|
||||||
|
headers.append('foo', 'baz');
|
||||||
|
expect(JSON.stringify(headers)).toEqual('{"FOO":["bar","baz"]}');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('.toJSON()', () => {
|
describe('.toJSON()', () => {
|
||||||
let headers: any /** TODO #9100 */ = null;
|
let headers: Headers;
|
||||||
let inputArr: any /** TODO #9100 */ = null;
|
let values: string[];
|
||||||
let obj: any /** TODO #9100 */ = null;
|
let ref: {[name: string]: string[]};
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
values = ['application/jeisen', 'application/jason', 'application/patrickjs'];
|
||||||
headers = new Headers();
|
headers = new Headers();
|
||||||
inputArr = ['application/jeisen', 'application/jason', 'application/patrickjs'];
|
headers.set('Accept', values);
|
||||||
obj = {'accept': inputArr};
|
ref = {'Accept': values};
|
||||||
headers.set('Accept', inputArr);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
it('should be serializable with toJSON', () => {
|
it('should be serializable with toJSON',
|
||||||
let stringifed = Json.stringify(obj);
|
() => { expect(JSON.stringify(headers)).toEqual(JSON.stringify(ref)); });
|
||||||
let serializedHeaders = Json.stringify(headers);
|
|
||||||
expect(serializedHeaders).toEqual(stringifed);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
it('should be able to parse serialized header', () => {
|
|
||||||
let stringifed = Json.stringify(obj);
|
|
||||||
let serializedHeaders = Json.stringify(headers);
|
|
||||||
expect(Json.parse(serializedHeaders)).toEqual(Json.parse(stringifed));
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
it('should be able to recreate serializedHeaders', () => {
|
it('should be able to recreate serializedHeaders', () => {
|
||||||
let serializedHeaders = Json.stringify(headers);
|
const parsedHeaders = JSON.parse(JSON.stringify(headers));
|
||||||
let parsedHeaders = Json.parse(serializedHeaders);
|
const recreatedHeaders = new Headers(parsedHeaders);
|
||||||
let recreatedHeaders = new Headers(parsedHeaders);
|
expect(JSON.stringify(parsedHeaders)).toEqual(JSON.stringify(recreatedHeaders));
|
||||||
expect(Json.stringify(parsedHeaders)).toEqual(Json.stringify(recreatedHeaders));
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -110,19 +148,15 @@ export function main() {
|
||||||
describe('.fromResponseHeaderString()', () => {
|
describe('.fromResponseHeaderString()', () => {
|
||||||
|
|
||||||
it('should parse a response header string', () => {
|
it('should parse a response header string', () => {
|
||||||
|
const response = `Date: Fri, 20 Nov 2015 01:45:26 GMT\n` +
|
||||||
let responseHeaderString = `Date: Fri, 20 Nov 2015 01:45:26 GMT
|
`Content-Type: application/json; charset=utf-8\n` +
|
||||||
Content-Type: application/json; charset=utf-8
|
`Transfer-Encoding: chunked\n` +
|
||||||
Transfer-Encoding: chunked
|
`Connection: keep-alive`;
|
||||||
Connection: keep-alive`;
|
const headers = Headers.fromResponseHeaderString(response);
|
||||||
|
expect(headers.get('Date')).toEqual('Fri, 20 Nov 2015 01:45:26 GMT');
|
||||||
let responseHeaders = Headers.fromResponseHeaderString(responseHeaderString);
|
expect(headers.get('Content-Type')).toEqual('application/json; charset=utf-8');
|
||||||
|
expect(headers.get('Transfer-Encoding')).toEqual('chunked');
|
||||||
expect(responseHeaders.get('Date')).toEqual('Fri, 20 Nov 2015 01:45:26 GMT');
|
expect(headers.get('Connection')).toEqual('keep-alive');
|
||||||
expect(responseHeaders.get('Content-Type')).toEqual('application/json; charset=utf-8');
|
|
||||||
expect(responseHeaders.get('Transfer-Encoding')).toEqual('chunked');
|
|
||||||
expect(responseHeaders.get('Connection')).toEqual('keep-alive');
|
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,19 +35,19 @@ export declare class CookieXSRFStrategy implements XSRFStrategy {
|
||||||
/** @experimental */
|
/** @experimental */
|
||||||
export declare class Headers {
|
export declare class Headers {
|
||||||
constructor(headers?: Headers | {
|
constructor(headers?: Headers | {
|
||||||
[key: string]: any;
|
[name: string]: any;
|
||||||
});
|
});
|
||||||
append(name: string, value: string): void;
|
append(name: string, value: string): void;
|
||||||
delete(name: string): void;
|
delete(name: string): void;
|
||||||
entries(): void;
|
entries(): void;
|
||||||
forEach(fn: (values: string[], name: string, headers: Map<string, string[]>) => void): void;
|
forEach(fn: (values: string[], name: string, headers: Map<string, string[]>) => void): void;
|
||||||
get(header: string): string;
|
get(name: string): string;
|
||||||
getAll(header: string): string[];
|
getAll(name: string): string[];
|
||||||
has(header: string): boolean;
|
has(name: string): boolean;
|
||||||
keys(): string[];
|
keys(): string[];
|
||||||
set(header: string, value: string | string[]): void;
|
set(name: string, value: string | string[]): void;
|
||||||
toJSON(): {
|
toJSON(): {
|
||||||
[key: string]: any;
|
[name: string]: any;
|
||||||
};
|
};
|
||||||
values(): string[][];
|
values(): string[][];
|
||||||
static fromResponseHeaderString(headersString: string): Headers;
|
static fromResponseHeaderString(headersString: string): Headers;
|
||||||
|
|
Loading…
Reference in New Issue