mirror of
https://github.com/wu736139669/RN_AWord.git
synced 2026-08-06 06:41:59 +00:00
436 lines
8.9 KiB
JavaScript
436 lines
8.9 KiB
JavaScript
/**
|
|
* Module of mixed-in functions shared between node and client code
|
|
*/
|
|
var isObject = require('./is-object');
|
|
|
|
/**
|
|
* Expose `RequestBase`.
|
|
*/
|
|
|
|
module.exports = RequestBase;
|
|
|
|
/**
|
|
* Initialize a new `RequestBase`.
|
|
*
|
|
* @api public
|
|
*/
|
|
|
|
function RequestBase(obj) {
|
|
if (obj) return mixin(obj);
|
|
}
|
|
|
|
/**
|
|
* Mixin the prototype properties.
|
|
*
|
|
* @param {Object} obj
|
|
* @return {Object}
|
|
* @api private
|
|
*/
|
|
|
|
function mixin(obj) {
|
|
for (var key in RequestBase.prototype) {
|
|
obj[key] = RequestBase.prototype[key];
|
|
}
|
|
return obj;
|
|
}
|
|
|
|
/**
|
|
* Clear previous timeout.
|
|
*
|
|
* @return {Request} for chaining
|
|
* @api public
|
|
*/
|
|
|
|
RequestBase.prototype.clearTimeout = function _clearTimeout(){
|
|
this._timeout = 0;
|
|
clearTimeout(this._timer);
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* Override default response body parser
|
|
*
|
|
* This function will be called to convert incoming data into request.body
|
|
*
|
|
* @param {Function}
|
|
* @api public
|
|
*/
|
|
|
|
RequestBase.prototype.parse = function parse(fn){
|
|
this._parser = fn;
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* Override default request body serializer
|
|
*
|
|
* This function will be called to convert data set via .send or .attach into payload to send
|
|
*
|
|
* @param {Function}
|
|
* @api public
|
|
*/
|
|
|
|
RequestBase.prototype.serialize = function serialize(fn){
|
|
this._serializer = fn;
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* Set timeout to `ms`.
|
|
*
|
|
* @param {Number} ms
|
|
* @return {Request} for chaining
|
|
* @api public
|
|
*/
|
|
|
|
RequestBase.prototype.timeout = function timeout(ms){
|
|
this._timeout = ms;
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* Promise support
|
|
*
|
|
* @param {Function} resolve
|
|
* @param {Function} reject
|
|
* @return {Request}
|
|
*/
|
|
|
|
RequestBase.prototype.then = function then(resolve, reject) {
|
|
if (!this._fullfilledPromise) {
|
|
var self = this;
|
|
this._fullfilledPromise = new Promise(function(innerResolve, innerReject){
|
|
self.end(function(err, res){
|
|
if (err) innerReject(err); else innerResolve(res);
|
|
});
|
|
});
|
|
}
|
|
return this._fullfilledPromise.then(resolve, reject);
|
|
}
|
|
|
|
RequestBase.prototype.catch = function(cb) {
|
|
return this.then(undefined, cb);
|
|
};
|
|
|
|
/**
|
|
* Allow for extension
|
|
*/
|
|
|
|
RequestBase.prototype.use = function use(fn) {
|
|
fn(this);
|
|
return this;
|
|
}
|
|
|
|
|
|
/**
|
|
* Get request header `field`.
|
|
* Case-insensitive.
|
|
*
|
|
* @param {String} field
|
|
* @return {String}
|
|
* @api public
|
|
*/
|
|
|
|
RequestBase.prototype.get = function(field){
|
|
return this._header[field.toLowerCase()];
|
|
};
|
|
|
|
/**
|
|
* Get case-insensitive header `field` value.
|
|
* This is a deprecated internal API. Use `.get(field)` instead.
|
|
*
|
|
* (getHeader is no longer used internally by the superagent code base)
|
|
*
|
|
* @param {String} field
|
|
* @return {String}
|
|
* @api private
|
|
* @deprecated
|
|
*/
|
|
|
|
RequestBase.prototype.getHeader = RequestBase.prototype.get;
|
|
|
|
/**
|
|
* Set header `field` to `val`, or multiple fields with one object.
|
|
* Case-insensitive.
|
|
*
|
|
* Examples:
|
|
*
|
|
* req.get('/')
|
|
* .set('Accept', 'application/json')
|
|
* .set('X-API-Key', 'foobar')
|
|
* .end(callback);
|
|
*
|
|
* req.get('/')
|
|
* .set({ Accept: 'application/json', 'X-API-Key': 'foobar' })
|
|
* .end(callback);
|
|
*
|
|
* @param {String|Object} field
|
|
* @param {String} val
|
|
* @return {Request} for chaining
|
|
* @api public
|
|
*/
|
|
|
|
RequestBase.prototype.set = function(field, val){
|
|
if (isObject(field)) {
|
|
for (var key in field) {
|
|
this.set(key, field[key]);
|
|
}
|
|
return this;
|
|
}
|
|
this._header[field.toLowerCase()] = val;
|
|
this.header[field] = val;
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* Remove header `field`.
|
|
* Case-insensitive.
|
|
*
|
|
* Example:
|
|
*
|
|
* req.get('/')
|
|
* .unset('User-Agent')
|
|
* .end(callback);
|
|
*
|
|
* @param {String} field
|
|
*/
|
|
RequestBase.prototype.unset = function(field){
|
|
delete this._header[field.toLowerCase()];
|
|
delete this.header[field];
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* Write the field `name` and `val`, or multiple fields with one object
|
|
* for "multipart/form-data" request bodies.
|
|
*
|
|
* ``` js
|
|
* request.post('/upload')
|
|
* .field('foo', 'bar')
|
|
* .end(callback);
|
|
*
|
|
* request.post('/upload')
|
|
* .field({ foo: 'bar', baz: 'qux' })
|
|
* .end(callback);
|
|
* ```
|
|
*
|
|
* @param {String|Object} name
|
|
* @param {String|Blob|File|Buffer|fs.ReadStream} val
|
|
* @return {Request} for chaining
|
|
* @api public
|
|
*/
|
|
RequestBase.prototype.field = function(name, val) {
|
|
|
|
// name should be either a string or an object.
|
|
if (null === name || undefined === name) {
|
|
throw new Error('.field(name, val) name can not be empty');
|
|
}
|
|
|
|
if (isObject(name)) {
|
|
for (var key in name) {
|
|
this.field(key, name[key]);
|
|
}
|
|
return this;
|
|
}
|
|
|
|
if (Array.isArray(val)) {
|
|
for (var i in val) {
|
|
this.field(name, val[i]);
|
|
}
|
|
return this;
|
|
}
|
|
|
|
// val should be defined now
|
|
if (null === val || undefined === val) {
|
|
throw new Error('.field(name, val) val can not be empty');
|
|
}
|
|
if ('boolean' === typeof val) {
|
|
val = '' + val;
|
|
}
|
|
this._getFormData().append(name, val);
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* Abort the request, and clear potential timeout.
|
|
*
|
|
* @return {Request}
|
|
* @api public
|
|
*/
|
|
RequestBase.prototype.abort = function(){
|
|
if (this._aborted) {
|
|
return this;
|
|
}
|
|
this._aborted = true;
|
|
this.xhr && this.xhr.abort(); // browser
|
|
this.req && this.req.abort(); // node
|
|
this.clearTimeout();
|
|
this.emit('abort');
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* Enable transmission of cookies with x-domain requests.
|
|
*
|
|
* Note that for this to work the origin must not be
|
|
* using "Access-Control-Allow-Origin" with a wildcard,
|
|
* and also must set "Access-Control-Allow-Credentials"
|
|
* to "true".
|
|
*
|
|
* @api public
|
|
*/
|
|
|
|
RequestBase.prototype.withCredentials = function(){
|
|
// This is browser-only functionality. Node side is no-op.
|
|
this._withCredentials = true;
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* Set the max redirects to `n`. Does noting in browser XHR implementation.
|
|
*
|
|
* @param {Number} n
|
|
* @return {Request} for chaining
|
|
* @api public
|
|
*/
|
|
|
|
RequestBase.prototype.redirects = function(n){
|
|
this._maxRedirects = n;
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* Convert to a plain javascript object (not JSON string) of scalar properties.
|
|
* Note as this method is designed to return a useful non-this value,
|
|
* it cannot be chained.
|
|
*
|
|
* @return {Object} describing method, url, and data of this request
|
|
* @api public
|
|
*/
|
|
|
|
RequestBase.prototype.toJSON = function(){
|
|
return {
|
|
method: this.method,
|
|
url: this.url,
|
|
data: this._data,
|
|
headers: this._header
|
|
};
|
|
};
|
|
|
|
|
|
/**
|
|
* Send `data` as the request body, defaulting the `.type()` to "json" when
|
|
* an object is given.
|
|
*
|
|
* Examples:
|
|
*
|
|
* // manual json
|
|
* request.post('/user')
|
|
* .type('json')
|
|
* .send('{"name":"tj"}')
|
|
* .end(callback)
|
|
*
|
|
* // auto json
|
|
* request.post('/user')
|
|
* .send({ name: 'tj' })
|
|
* .end(callback)
|
|
*
|
|
* // manual x-www-form-urlencoded
|
|
* request.post('/user')
|
|
* .type('form')
|
|
* .send('name=tj')
|
|
* .end(callback)
|
|
*
|
|
* // auto x-www-form-urlencoded
|
|
* request.post('/user')
|
|
* .type('form')
|
|
* .send({ name: 'tj' })
|
|
* .end(callback)
|
|
*
|
|
* // defaults to x-www-form-urlencoded
|
|
* request.post('/user')
|
|
* .send('name=tobi')
|
|
* .send('species=ferret')
|
|
* .end(callback)
|
|
*
|
|
* @param {String|Object} data
|
|
* @return {Request} for chaining
|
|
* @api public
|
|
*/
|
|
|
|
RequestBase.prototype.send = function(data){
|
|
var isObj = isObject(data);
|
|
var type = this._header['content-type'];
|
|
|
|
if (isObj && !this._data) {
|
|
if (Array.isArray(data)) {
|
|
this._data = [];
|
|
} else if (!this._isHost(data)) {
|
|
this._data = {};
|
|
}
|
|
} else if (data && this._data && this._isHost(this._data)) {
|
|
throw Error("Can't merge these send calls");
|
|
}
|
|
|
|
// merge
|
|
if (isObj && isObject(this._data)) {
|
|
for (var key in data) {
|
|
this._data[key] = data[key];
|
|
}
|
|
} else if ('string' == typeof data) {
|
|
// default to x-www-form-urlencoded
|
|
if (!type) this.type('form');
|
|
type = this._header['content-type'];
|
|
if ('application/x-www-form-urlencoded' == type) {
|
|
this._data = this._data
|
|
? this._data + '&' + data
|
|
: data;
|
|
} else {
|
|
this._data = (this._data || '') + data;
|
|
}
|
|
} else {
|
|
this._data = data;
|
|
}
|
|
|
|
if (!isObj || this._isHost(data)) return this;
|
|
|
|
// default to json
|
|
if (!type) this.type('json');
|
|
return this;
|
|
};
|
|
|
|
|
|
/**
|
|
* Sort `querystring` by the sort function
|
|
*
|
|
*
|
|
* Examples:
|
|
*
|
|
* // default order
|
|
* request.get('/user')
|
|
* .query('name=Nick')
|
|
* .query('search=Manny')
|
|
* .sortQuery()
|
|
* .end(callback)
|
|
*
|
|
* // customized sort function
|
|
* request.get('/user')
|
|
* .query('name=Nick')
|
|
* .query('search=Manny')
|
|
* .sortQuery(function(a, b){
|
|
* return a.length - b.length;
|
|
* })
|
|
* .end(callback)
|
|
*
|
|
*
|
|
* @param {Function} sort
|
|
* @return {Request} for chaining
|
|
* @api public
|
|
*/
|
|
|
|
RequestBase.prototype.sortQuery = function(sort) {
|
|
// _sort default to true but otherwise can be a function or boolean
|
|
this._sort = typeof sort === 'undefined' ? true : sort;
|
|
return this;
|
|
};
|