xhr.js
2.66 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
var curry = require('./curry'),
map = require('./map'),
each = require('./each'),
json = require('./json')
module.exports = {
request: request,
get: curry(request, 'get'),
post: curry(request, 'post'),
jsonGet: curry(sendJSON, 'get'),
jsonPost: curry(sendJSON, 'post')
}
var XHR = window.XMLHttpRequest || function() { return new ActiveXObject("Msxml2.XMLHTTP"); }
var onBeforeUnloadFired = false
function onBeforeUnload() {
onBeforeUnloadFired = true
setTimeout(function(){ onBeforeUnloadFired = false }, 100)
}
if (window.addEventListener) { window.addEventListener('beforeunload', onBeforeUnload, false) }
else { window.attachEvent('onbeforeunload', onBeforeUnload) }
function request(method, url, params, callback, headers, opts) {
var xhr = new XHR()
method = method.toUpperCase()
headers = headers || {}
opts = opts || {}
xhr.onreadystatechange = function() {
var err, result
try {
if (xhr.readyState != 4) { return }
if (onBeforeUnloadFired) { return }
var text = xhr.responseText,
isJson = xhr.getResponseHeader('Content-Type') == 'application/json'
if (xhr.status == 200 || xhr.status == 204) {
result = isJson ? json.parse(text) : text
} else {
try { err = isJson ? json.parse(text) : new Error(text) }
catch (e) { err = new Error(text) }
}
} catch(e) {
err = e
}
if (err || typeof result != undefined) {
_abortXHR(xhr)
callback(err, result)
}
}
var uriEncode = (opts.encode === false
? function(params) { return map(params, function(val, key) { return key+'='+val }).join('&') }
: function(params) { return map(params, function(val, key) { return encodeURIComponent(key)+'='+encodeURIComponent(val) }).join('&') })
var data = ''
if (method == 'GET') {
var queryParams = uriEncode(params)
url += (url.indexOf('?') == -1 && queryParams ? '?' : '') + queryParams
} else if (method == 'POST') {
var contentType = headers['Content-Type']
if (!contentType) {
contentType = headers['Content-Type'] = 'application/x-www-form-urlencoded'
}
if (contentType == 'application/x-www-form-urlencoded') {
data = uriEncode(params)
} else if (contentType == 'application/json') {
data = json.stringify(params)
}
}
xhr.open(method, url, true)
each(headers, function(val, key) { xhr.setRequestHeader(key, val) })
xhr.send(data)
}
function sendJSON(method, url, params, callback) {
return request(method, url, params, callback, { 'Content-Type':'application/json' })
}
function _abortXHR(xhr) {
try {
if('onload' in xhr) {
xhr.onload = xhr.onerror = xhr.ontimeout = null;
} else if('onreadystatechange' in xhr) {
xhr.onreadystatechange = null;
}
if(xhr.abort) { xhr.abort(); }
} catch(e) {}
}