/
xhr.js
92 lines (83 loc) · 2.28 KB
/
xhr.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import { fetch } from './fetch.js';
import { Evented } from './evented.js';
// XHR States
const UNSENT = 0;
const OPENED = 1;
const DONE = 4;
// Extends from Evented to fire events
export class XMLHttpRequest extends Evented {
constructor() {
super();
this.headers = {};
this.readyState = UNSENT;
this.withCredentials = true;
}
// Stores method and url
open(method, url) {
this.readyState = OPENED;
this.method = method;
this.url = url;
}
/**
* Resets status and values
* Needed by some implementations
*/
abort() {
this.readyState = UNSENT;
this.responseText = '';
this.response = null;
this.status = null;
}
// Append header to headers object
setRequestHeader(name, value) {
this.headers[name] = value;
}
/**
* A ByteString representing all of the response's headers (except those
* whose field name is Set-Cookie or Set-Cookie2) separated by CRLF, or null
* if no response has been received.
*/
getAllResponseHeaders() {
return this.responseHeaders ? Object.keys(this.responseHeaders)
.filter(key => key.toLowerCase() !== 'set-cookie' && key.toLowerCase() !== 'set-cookie2')
.map(key => `${key}: ${this.responseHeaders[key]}`)
.join('\r\n') : null;
}
/**
* Uses fetch to fire request
* Fires both load and readystatechange so registered components know data was loaded
*/
send(body) {
fetch(this.url, { method: this.method, body })
.then(res => {
this.readyState = DONE;
this.status = res.status;
this.statusText = res.statusText;
this.redirected = res.redirected;
this.responseHeaders = res.headers;
if (this.responseType === 'arraybuffer') {
this.bodyField = 'response';
return res.arrayBuffer();
} else {
this.bodyField = 'responseText';
return res.text();
}
})
.then(
body => {
this.response = body;
this[this.bodyField] = body;
this.emit('readystatechange', body);
this.emit('load', body);
},
err => {
this.abort();
this.emit('error', err);
}
);
}
// Get response header by key
getResponseHeader(key) {
return this.responseHeaders.get(key);
}
}