UNPKG

ks3-js-sdk

Version:

js sdk for ks3

273 lines (247 loc) 8.27 kB
var stringifyPrimitive = function (v) { switch (typeof v) { case 'string': return v; case 'boolean': return v ? 'true' : 'false'; case 'number': return isFinite(v) ? v : ''; default: return ''; } }; /** * Changes XML DOM to JSON (xml 不带属性) * @param xml * @returns {{}} js对象 */ var xmlToJson = function (xml) { // Create the return object var obj = {}; if (!xml) { return obj; } if (xml.nodeType == Node.TEXT_NODE) { // text obj = xml.nodeValue; } // do children if (xml.hasChildNodes()) { for (var i = 0; i < xml.childNodes.length; i++) { var item = xml.childNodes.item(i); var nodeName = item.nodeName; if (typeof (obj[nodeName]) == "undefined") { if (nodeName === '#text') { // 待优化。。。。Error情况下返回的responseXml数据带\n冗余字符 会解析错误 if (item.nodeValue.indexOf('\n') == -1) { obj = item.nodeValue; } } else { obj[nodeName] = xmlToJson(item); } } else {//同级同标签转化为数组 if (typeof (obj[nodeName].length) == "undefined") { var old = obj[nodeName]; obj[nodeName] = []; obj[nodeName].push(old); } obj[nodeName].push(xmlToJson(item)); } } } return obj; }; var queryStringify = function (obj, sep, eq, name) { sep = sep || '&'; eq = eq || '='; if (obj === null) { obj = undefined; } if (typeof obj === 'object') { return Object.keys(obj).map(function (k) { var ks = encodeURIComponent(stringifyPrimitive(k)) + eq; if (!obj[k]) { return ''; } if (Array.isArray(obj[k])) { return obj[k].map(function (v) { return ks + encodeURIComponent(stringifyPrimitive(v)); }).join(sep); } else { return ks + encodeURIComponent(stringifyPrimitive(obj[k])); } }).filter(Boolean).join(sep); } if (!name) return ''; return encodeURIComponent(stringifyPrimitive(name)) + eq + encodeURIComponent(stringifyPrimitive(obj)); }; var xhrRes = function (err, xhr, body) { var headers = {}; xhr.getAllResponseHeaders().trim().split('\n').forEach(function (item) { if (item) { var index = item.indexOf(':'); var key = item.substr(0, index).trim().toLowerCase(); var val = item.substr(index + 1).trim(); headers[key] = val; } }); return { error: err, statusCode: xhr.status, statusMessage: xhr.statusText, headers: headers, body: body, }; }; var xhrBody = function (xhr, dataType) { return !dataType && dataType === 'text' ? xhr.responseText : xhr.response; }; var request = function (opt, callback) { // method var method = (opt.method || 'GET').toUpperCase(); // url、qs var url = opt.url; if (opt.qs) { var qsStr = queryStringify(opt.qs); if (qsStr) { url += (url.indexOf('?') === -1 ? '?' : '&') + qsStr; } } // 创建 ajax 实例 var xhr = new XMLHttpRequest(); xhr.open(method, url, true); // xhr.responseType = opt.dataType || 'text'; // 处理 xhrFields 属性 // if (opt.xhrFields) { // for (var xhrField in opt.xhrFields) { // xhr[xhrField] = opt.xhrFields[xhrField] // } // } // 处理 headers var headers = opt.headers; if (headers) { for (var key in headers) { if (headers.hasOwnProperty(key) && key.toLowerCase() !== 'content-length' && key.toLowerCase() !== 'user-agent' && key.toLowerCase() !== 'origin' && key.toLowerCase() !== 'host') { xhr.setRequestHeader(key, headers[key]); } } } // onprogress if (opt.onProgress && xhr.upload) xhr.upload.onprogress = opt.onProgress; if (opt.onDownloadProgress) xhr.onprogress = opt.onDownloadProgress; // timeout if (opt.timeout) xhr.timeout = opt.timeout; xhr.ontimeout = function (event) { var error = new Error('timeout'); callback(xhrRes(error, xhr)); }; // success 2xx/3xx/4xx xhr.onload = function () { if (xhr.status === 404) { callback(xhrRes(null, xhr, null)); return; } if (xhr.status < 500 && xhr.status > 400) { var err = xhr.responseXML ? xmlToJson(xhr.responseXML) : ''; callback(xhrRes(xhr.responseXML ? err : '', xhr, null)); return; } let res = '' if (xhr.responseType) { res = this.response } else { res = xhr.responseXML ? xmlToJson(xhr.responseXML) : '' } callback(xhrRes(null, xhr, res)); }; // error 5xx/0 (网络错误、跨域报错、Https connect-src 限制的报错时 statusCode 为 0) xhr.onerror = function (err) { var body = xhrBody(xhr, opt.dataType); if (body) { // 5xx callback(xhrRes(null, xhr, body)); } else { // 0 var error = xhr.statusText; if (!error && xhr.status === 0) error = {Error: 'CORS blocked or network error'} callback(xhrRes(error, xhr, body)); throw new Error('CORS blocked or network error'); } }; if (opt.responseType) { xhr.responseType = opt.responseType } // send xhr.send(opt.body || null); // 返回 ajax 实例,用于外部调用 xhr.abort return xhr; }; // 构建请求 sender var submitRequest = function (params, cb) { var self = this; var taskId = params.taskId; if (taskId && !self._isRunningTask(taskId)) return; var method = params.method || 'GET'; var url = params.Url || params.url; var body = params.body; var opt = { method: method, url: url, headers: params.headers, qs: params.qs, body: body, date: params.date, onProgress: params.onProgress, responseType: params.responseType }; if (this.config.securityToken) { opt.headers['X-Ksc-Security-Token'] = this.config.securityToken } if (method === 'POST') { // opt.headers[''] = '*' } if (this.config.timeout) { opt.timeout = this.config.timeout; } var sender = request(opt, (response) => { // 网络错误 if (response.error) { cb(response.error, null) } // 请求返回码不为 200 var statusCode = response.statusCode; var statusSuccess = Math.floor(statusCode / 100) === 2; // 200 202 204 206 // 解析 xml body var json; try { json = (response.body && body.indexOf('<') > -1 && response.body.indexOf('>') > -1 && xmlToJson(response.body)) || {}; } catch (e) { json = {}; } // 处理返回值 var xmlError = json && json.Error; if (statusSuccess) { // 正确返回,状态码 2xx 时,body 不会有 Error cb(null, response); } else if (xmlError) { // 正常返回了 xml body,且有 Error 节点 cb(new Error(xmlError.Message), { code: xmlError.Code, error: xmlError }); } else if (statusCode) { // 有错误的状态码 cb(new Error(response.statusMessage), response); } else { // 无状态码,或者获取不到状态码 cb(new Error('statusCode error')); } }) var killTask = function (data) { if (data.taskId === taskId) { sender && sender.abort && sender.abort(); self.off('inner-kill-task', killTask); } }; taskId && self.on('inner-kill-task', killTask); } module.exports = submitRequest;