/
ajaxCore.js
118 lines (102 loc) · 2.99 KB
/
ajaxCore.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
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
"use strict";
var request = require('./request');
var extend = require('js-extend').extend;
var errors = require('./../errors');
var clone = require('../../deps/clone');
var applyTypeToBuffer = require('./applyTypeToBuffer');
var defaultBody = require('./defaultBody');
function ajax(options, callback) {
options = clone(options);
var defaultOptions = {
method : "GET",
headers: {},
json: true,
processData: true,
timeout: 10000,
cache: false
};
options = extend(defaultOptions, options);
function onSuccess(obj, resp, cb) {
if (!options.binary && options.json && typeof obj === 'string') {
try {
obj = JSON.parse(obj);
} catch (e) {
// Probably a malformed JSON from server
return cb(e);
}
}
if (Array.isArray(obj)) {
obj = obj.map(function (v) {
if (v.error || v.missing) {
return errors.generateErrorFromResponse(v);
} else {
return v;
}
});
}
if (options.binary) {
applyTypeToBuffer(obj, resp);
}
cb(null, obj, resp);
}
function onError(err, cb) {
var errParsed, errObj;
if (err.code && err.status) {
var err2 = new Error(err.message || err.code);
err2.status = err.status;
return cb(err2);
}
// We always get code && status in node
/* istanbul ignore next */
try {
errParsed = JSON.parse(err.responseText);
//would prefer not to have a try/catch clause
errObj = errors.generateErrorFromResponse(errParsed);
} catch (e) {
errObj = errors.generateErrorFromResponse(err);
}
/* istanbul ignore next */
cb(errObj);
}
if (options.json) {
if (!options.binary) {
options.headers.Accept = 'application/json';
}
options.headers['Content-Type'] = options.headers['Content-Type'] ||
'application/json';
}
if (options.binary) {
options.encoding = null;
options.json = false;
}
if (!options.processData) {
options.json = false;
}
return request(options, function (err, response, body) {
if (err) {
err.status = response ? response.statusCode : 400;
return onError(err, callback);
}
var error;
var content_type = response.headers && response.headers['content-type'];
var data = body || defaultBody();
// CouchDB doesn't always return the right content-type for JSON data, so
// we check for ^{ and }$ (ignoring leading/trailing whitespace)
if (!options.binary && (options.json || !options.processData) &&
typeof data !== 'object' &&
(/json/.test(content_type) ||
(/^[\s]*\{/.test(data) && /\}[\s]*$/.test(data)))) {
try {
data = JSON.parse(data.toString());
} catch (e) {}
}
if (response.statusCode >= 200 && response.statusCode < 300) {
onSuccess(data, response, callback);
} else {
error = errors.generateErrorFromResponse(data);
error.status = response.statusCode;
callback(error);
}
});
}
module.exports = ajax;