forked from javascript-tutorial/server
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathxhr.js
More file actions
executable file
·150 lines (121 loc) · 4.22 KB
/
xhr.js
File metadata and controls
executable file
·150 lines (121 loc) · 4.22 KB
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
var notification = require('client/notification');
var getCsrfCookie = require('client/getCsrfCookie');
// Wrapper about XHR
// # Global Events
// triggers document.loadstart/loadend on communication start/end
// --> unless options.noGlobalEvents is set
//
// # Events
// triggers fail/success on load end:
// --> by default status=200 is ok, the others are failures
// --> options.normalStatuses = [201,409] allow given statuses
// --> fail event has .reason field
// --> success event has .result field
//
// # JSON
// --> send(object) calls JSON.stringify
// --> adds Accept: json (we want json) by default, unless options.raw
// if options.json or server returned json content type
// --> autoparse json
// --> fail if error
//
// # CSRF
// --> requests sends header X-XSRF-TOKEN from cookie
function xhr(options) {
var request = new XMLHttpRequest();
var method = options.method || 'GET';
var body = options.body;
var url = options.url;
request.open(method, url, options.sync ? false : true);
request.method = method;
// token/header names same as angular $http for easier interop
var csrfCookie = getCsrfCookie();
if (csrfCookie && !options.skipCsrf) {
request.setRequestHeader("X-XSRF-TOKEN", csrfCookie);
}
if ({}.toString.call(body) == '[object Object]') {
// must be OPENed to setRequestHeader
request.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
body = JSON.stringify(body);
}
if (!options.noDocumentEvents) {
request.addEventListener('loadstart', event => {
request.timeStart = Date.now();
var e = wrapEvent('xhrstart', event);
document.dispatchEvent(e);
});
request.addEventListener('loadend', event => {
var e = wrapEvent('xhrend', event);
document.dispatchEvent(e);
});
request.addEventListener('success', event => {
var e = wrapEvent('xhrsuccess', event);
e.result = event.result;
document.dispatchEvent(e);
});
request.addEventListener('fail', event => {
var e = wrapEvent('xhrfail', event);
e.reason = event.reason;
document.dispatchEvent(e);
});
}
if (!options.raw) { // means we want json
request.setRequestHeader("Accept", "application/json");
}
request.setRequestHeader('X-Requested-With', "XMLHttpRequest");
var normalStatuses = options.normalStatuses || [200];
function wrapEvent(name, e) {
var event = new CustomEvent(name);
event.originalEvent = e;
return event;
}
function fail(reason, originalEvent) {
var e = wrapEvent("fail", originalEvent);
e.reason = reason;
request.dispatchEvent(e);
}
function success(result, originalEvent) {
var e = wrapEvent("success", originalEvent);
e.result = result;
request.dispatchEvent(e);
}
request.addEventListener("error", e => {
fail("Ошибка связи с сервером.", e);
});
request.addEventListener("timeout", e => {
fail("Превышено максимально допустимое время ожидания ответа от сервера.", e);
});
request.addEventListener("abort", e => {
fail("Запрос был прерван.", e);
});
request.addEventListener("load", e => {
if (!request.status) { // does that ever happen?
fail("Не получен ответ от сервера.", e);
return;
}
if (normalStatuses.indexOf(request.status) == -1) {
fail("Ошибка на стороне сервера (код " + request.status + "), попытайтесь позднее.", e);
return;
}
var result = request.responseText;
var contentType = request.getResponseHeader("Content-Type");
if (contentType.match(/^application\/json/) || options.json) { // autoparse json if WANT or RECEIVED json
try {
result = JSON.parse(result);
} catch (e) {
fail("Некорректный формат ответа от сервера.", e);
return;
}
}
success(result, e);
});
// defer to let other handlers be assigned
setTimeout(function() {
request.send(body);
}, 0);
return request;
}
document.addEventListener('xhrfail', function(event) {
new notification.Error(event.reason);
});
module.exports = xhr;