UNPKG

@writ/utils

Version:
222 lines (211 loc) 6.81 kB
const noop = require('./noop'); const addQuery = require('./request-query-add'); /** * 获取对应的的请求对象 * XMLRequest对象在高版本标准浏览器里是不存在参数的,传入参数值不会影响其运行 **/ function getXhr(any) { return new XMLRequest(any || XMLRequest.microsoft); } /** * 获取返回数据 * @param {XMLHttpRequest} xhr */ function getBody(xhr) { var text = xhr.responseText || xhr.response; if (!text) { return text; } try { return JSON.parse(text); } catch (e) { return text; } } // -------------------------------------------------------- // utlis end / /** * 全局缓存 XMLHttpRequest 对象 * @desc xhr.setRequestHeader('If-Modified-Since', '0'); 禁用缓存 * @desc get head post put delete connect options trace patch * GET 方法请求一个指定资源的表示形式.使用GET的请求应该只被用于获取数据. * HEAD 方法请求一个与GET请求的响应相同的响应, 但没有响应体. * POST 方法用于将实体提交到指定的资源, 通常导致状态或服务器上的副作用的更改. * PUT 方法用请求有效载荷替换目标资源的所有当前表示。 * DELETE 方法删除指定的资源。 * CONNECT 方法建立一个到由目标资源标识的服务器的隧道。 * OPTIONS 方法用于描述目标资源的通信选项。 * TRACE 方法沿着到目标资源的路径执行一个消息环回测试。 * PATCH 方法用于对资源应用部分修改 **/ var XMLRequest = null; if (XMLHttpRequest) { XMLRequest = XMLHttpRequest; } else { XMLRequest = ActiveXObject; XMLRequest.microsoft = 'Microsoft.XMLHTTP'; } var CONFIG = { /** @param {string} method http连接的方式,包括POST和GET两种方式 */ method: 'GET', /** @param {string} url 发送请求的url */ url: undefined, /** @param {boolean} async 是否为异步请求,true为异步的,false为同步的 */ async: true, /** @param {string} ie 传递给 ie 低版本的参数 */ ie: undefined, /** @param {object} data 发送的参数,格式为对象类型 */ data: null, /** @param {string} query 添加到URL上的参数 */ query: undefined, /** @param {object} headers 发送的请求头,格式为对象类型 */ headers: null, /** @param {boolean} cache 是否 URL 缓存请求 */ cache: false, /** @param {boolean} withCredentials 是否发送cookie */ withCredentials: true, /** @param {object} timeout 请求超时时间 */ timeout: 50000, /** @param {function} onBefore 发送前执行的回调函数 */ onBefore: noop, /** @param {function} onSuccess 发送并接收成功调用的回调函数 */ onSuccess: noop, /** @param {function} onError 请求出错时执行的回调函数 */ onError: noop, /** @param {function} onFinally 请求完成执行的回调函数 */ onFinally: noop, /** @param {function} onTimeout 请求超时 */ onTimeout: noop, /** @param {function} onProgress 上传进度处理 */ onProgress: noop, /** @param {function} onload 上传结束 */ onload: noop, }; /** * 合并配置到基础选项上 * @param {object} key - user options * @param {..any} value - user options' value */ function setConfig(key, value) { if (arguments.length > 1) { if (key in CONFIG) { CONFIG[key] = value; return; } } if (typeof key !== 'object') { throw new Error('key must be an object.'); } for (var k in key) { if (k in CONFIG) { value = key[k]; if (typeof value === 'undefined') continue; CONFIG[k] = value; } } } /** * 合并请求参数 * @param {CONFIG} opt */ function getOption(opt) { var option = Object.assign({}, CONFIG, opt); if (!option.url) { throw new Error('Invalid Request URL'); } option.method = (opt.method || CONFIG.method).toUpperCase(); option.timeout = option.timeout > 0 ? option.timeout : CONFIG.timeout; option.onBefore = typeof option.onBefore !== 'function' ? CONFIG.onBefore : option.onBefore; option.onSuccess = typeof option.onSuccess !== 'function' ? CONFIG.onSuccess : option.onSuccess; option.onError = typeof option.onError !== 'function' ? CONFIG.onError : option.onError; option.onFinally = typeof option.onFinally !== 'function' ? CONFIG.onFinally : option.onFinally; option.onProgress = typeof option.onProgress !== 'function' ? CONFIG.onProgress : option.onProgress; option.onTimeout = typeof option.onTimeout !== 'function' ? CONFIG.onTimeout : option.onTimeout; option.onload = typeof option.onload !== 'function' ? CONFIG.onload : option.onload; return option; } /** * 发送请求 * @param {CONFIG} opts */ function request(opts) { var data; var opt = getOption(opts); var xhr = getXhr(opt.ie); var headers = opt.headers || {}; opt.url += addQuery(opt.method, opt.query, opt.data, opt.cache); if (opt.onBefore(xhr, opt) === false) { return; } xhr.timeout = opt.timeout; xhr.ontimeout = opt.onTimeout; xhr.onload = opt.onload; xhr.onerror = opt.onError; if (xhr.upload) { xhr.upload.onprogress = function progress(x, e) { if (x.total > 0) { x.percent = x.loaded / x.total * 100; } opt.onProgress(x, e); }; } else { xhr.onprogress = opt.onProgress; } xhr.onreadystatechange = function (xhr, e) { if (xhr.readyState === 4) { var body = getBody(xhr); if (xhr.status < 200 || xhr.status >= 300) { opt.onError(xhr, e, body); } else { opt.onSuccess(body, xhr); } } opt.onFinally(xhr, e); }; xhr.open(opt.method, opt.url, opt.async); if (opt.withCredentials && 'withCredentials' in xhr) { xhr.withCredentials = true; } // when set headers['X-Requested-With'] = null , can close default XHR header // see https://github.com/react-component/upload/issues/33 if (headers['X-Requested-With'] !== null) { xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); } // 禁用缓存 if (opt.cache === false && headers['If-Modified-Since'] == null) { xhr.setRequestHeader('If-Modified-Since', '0'); } for (var h in headers) { if (headers.hasOwnProperty(h) && headers[h] !== null) { xhr.setRequestHeader(h, headers[h]); } } xhr.send(data || null); return xhr; } module.exports = { request, setConfig, http: { post(url, data, success, error, progress) { return request({ data, method: 'post', onError: error, onSuccess: success, onProgress: progress, url, }); }, get(url, data, success, error, progress) { return request({ data, method: 'get', onError: error, onSuccess: success, onProgress: progress, url, }); } }, };