blob: 1aed7631144cbeae06b7557280e9f2523bb9f394 (
plain)
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
|
'use strict';
module.exports = jsonpRequest;
var errors = require('../errors');
var JSONPCounter = 0;
function jsonpRequest(url, opts, cb) {
if (opts.method !== 'GET') {
cb(new Error('Method ' + opts.method + ' ' + url + ' is not supported by JSONP.'));
return;
}
opts.debug('JSONP: start');
var cbCalled = false;
var timedOut = false;
JSONPCounter += 1;
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
var cbName = 'algoliaJSONP_' + JSONPCounter;
var done = false;
window[cbName] = function(data) {
removeGlobals();
if (timedOut) {
opts.debug('JSONP: Late answer, ignoring');
return;
}
cbCalled = true;
clean();
cb(null, {
body: data,
responseText: JSON.stringify(data)/* ,
// We do not send the statusCode, there's no statusCode in JSONP, it will be
// computed using data.status && data.message like with XDR
statusCode*/
});
};
// add callback by hand
url += '&callback=' + cbName;
// add body params manually
if (opts.jsonBody && opts.jsonBody.params) {
url += '&' + opts.jsonBody.params;
}
var ontimeout = setTimeout(timeout, opts.timeouts.complete);
// script onreadystatechange needed only for
// <= IE8
// https://github.com/angular/angular.js/issues/4523
script.onreadystatechange = readystatechange;
script.onload = success;
script.onerror = error;
script.async = true;
script.defer = true;
script.src = url;
head.appendChild(script);
function success() {
opts.debug('JSONP: success');
if (done || timedOut) {
return;
}
done = true;
// script loaded but did not call the fn => script loading error
if (!cbCalled) {
opts.debug('JSONP: Fail. Script loaded but did not call the callback');
clean();
cb(new errors.JSONPScriptFail());
}
}
function readystatechange() {
if (this.readyState === 'loaded' || this.readyState === 'complete') {
success();
}
}
function clean() {
clearTimeout(ontimeout);
script.onload = null;
script.onreadystatechange = null;
script.onerror = null;
head.removeChild(script);
}
function removeGlobals() {
try {
delete window[cbName];
delete window[cbName + '_loaded'];
} catch (e) {
window[cbName] = window[cbName + '_loaded'] = undefined;
}
}
function timeout() {
opts.debug('JSONP: Script timeout');
timedOut = true;
clean();
cb(new errors.RequestTimeout());
}
function error() {
opts.debug('JSONP: Script error');
if (done || timedOut) {
return;
}
clean();
cb(new errors.JSONPScriptError());
}
}
|