Last active
July 6, 2020 11:26
-
-
Save daixianceng/a5968a55dabd4f04554dc3b27da9fcd3 to your computer and use it in GitHub Desktop.
Pure javascript ajax request
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| var sha256 = require('sha256'); | |
| var baseUrl = 'http://127.0.0.1:8000'; | |
| var securityKey = '****'; | |
| var encryptSalt = '****'; | |
| /** | |
| * 纯js实现的ajax | |
| * | |
| * ```js | |
| * request.ajax( | |
| * url: '', // 完整的url | |
| * path: '', // 路径,将会与`baseUrl`拼装 | |
| * method: 'POST', // 方法,默认GET | |
| * json: {}, // json数据 | |
| * form: new FormData(), // 使用`FormData`自定义数据 | |
| * sign: true, // 是否对json数据进行签名,默认true | |
| * timeout: 30000, // 超时时间 | |
| * responseType: 'json', // 响应格式 | |
| * headers: {}, // 请求头 | |
| * success: data => {}, // 成功回调 | |
| * fail: data => {}, // 失败回调 | |
| * error: err => {}, // 错误回调,err有多种变体 | |
| * complete: res => {}, // 完成回调 | |
| * abort: err => {}, // 取消回调 | |
| * ); | |
| * ``` | |
| * | |
| * Note: 该库默认请求与接收JSON数据,且加入了签名功能 | |
| * | |
| * 关闭签名功能:request.ajax({ sign: false }); | |
| */ | |
| module.exports = { | |
| _headers: { | |
| 'Content-Type': 'application/json;charset=utf-8', | |
| 'Security-Key': securityKey, | |
| }, | |
| addHeaders(headers) { | |
| this._headers = Object.assign({}, this._headers, headers); | |
| }, | |
| getHeaders() { | |
| return this._headers; | |
| }, | |
| removeHeader(key) { | |
| delete this._headers[key]; | |
| }, | |
| /** | |
| * 发起请求 | |
| * | |
| * @param object options | |
| * @return object XMLHttpRequest | |
| */ | |
| ajax(options) { | |
| var oReq = new XMLHttpRequest(); | |
| oReq.responseType = options.responseType || 'json'; | |
| oReq.timeout = options.timeout || 30000; | |
| oReq.open(options.method || 'GET', options.url || baseUrl + options.path); | |
| var headers = options.headers | |
| ? Object.assign({}, this._headers, options.headers) | |
| : this._headers; | |
| this._setHeaders(oReq, headers); | |
| var isSign = options.sign === false ? false : true; | |
| var json = null; | |
| if (options.json) { | |
| if (isSign) { | |
| json = { | |
| ...options.json, | |
| sign: this.sign(options.json), | |
| }; | |
| } else { | |
| json = options.json; | |
| } | |
| } | |
| oReq.onreadystatechange = function () { | |
| try { | |
| if (oReq.readyState === 4) { | |
| if (oReq.response) { | |
| if (oReq.response.status === 'success') { | |
| if (options.success) { | |
| options.success(oReq.response.data, oReq); | |
| } | |
| } else if (oReq.response.status === 'fail') { | |
| if (options.fail) { | |
| options.fail(oReq.response.data, oReq); | |
| } | |
| } else if (oReq.response.status === 'error') { | |
| if (options.error) { | |
| options.error(oReq.response.data, oReq); | |
| } | |
| } | |
| } | |
| if (options.complete) { | |
| options.complete(oReq.response, oReq); | |
| } | |
| } | |
| } catch (e) { | |
| if (options.error) { | |
| options.error(e, oReq); | |
| } | |
| } | |
| }; | |
| oReq.addEventListener('abort', function (e) { | |
| if (options.abort) { | |
| options.abort(e, oReq); | |
| } | |
| }); | |
| oReq.addEventListener('error', function (e) { | |
| if (options.error) { | |
| options.error(e, oReq); | |
| } | |
| }); | |
| oReq.addEventListener('timeout', function (e) { | |
| if (options.error) { | |
| options.error(e, oReq); | |
| } | |
| }); | |
| if (json) { | |
| oReq.send(JSON.stringify(json)); | |
| } else if (options.form) { | |
| oReq.send(form); | |
| } else { | |
| oReq.send(); | |
| } | |
| return oReq; | |
| }, | |
| _retryCounts: {}, | |
| /** | |
| * 可以发起重试的ajax | |
| * | |
| * 按理来说,应始终使用该方法来发起请求 | |
| * | |
| * @param options options | |
| */ | |
| retryAjax(options, key) { | |
| key = key || Math.random(); | |
| if (this._retryCounts[key] === undefined) this._retryCounts[key] = 0; | |
| this._retryCounts[key]++; | |
| this.ajax({ | |
| ...options, | |
| success: (...args) => { | |
| delete this._retryCounts[key]; | |
| options.success && options.success(...args); | |
| }, | |
| fail: (...args) => { | |
| if (this._retryCounts[key] > 3) { | |
| delete this._retryCounts[key]; | |
| options.fail && options.fail(...args); | |
| // show toast | |
| } else { | |
| setTimeout(() => this.retryAjax(options, key), 3000); | |
| } | |
| }, | |
| error: (...args) => { | |
| if (this._retryCounts[key] > 3) { | |
| delete this._retryCounts[key]; | |
| options.error && options.error(...args); | |
| // show toast | |
| } else { | |
| setTimeout(() => this.retryAjax(options, key), 3000); | |
| } | |
| }, | |
| }); | |
| }, | |
| _setHeaders(oReq, headers) { | |
| for (var key in headers) { | |
| oReq.setRequestHeader(key, headers[key]); | |
| } | |
| }, | |
| sign(args) { | |
| var keys = Object.keys(args); | |
| keys.sort(); | |
| var sa = []; | |
| keys.forEach((k) => { | |
| if (args[k]) { | |
| sa.push(k + '=' + args[k]); | |
| } | |
| }); | |
| sa.push('salt:' + encryptSalt); | |
| return sha256.hex(sa.join('&'), 'utf8').toUpperCase(); | |
| }, | |
| }; |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
这是我在游戏中使用的代码,经过了生产测试,完美无瑕!其中默认使用了签名功能和
JSON,可以在我的基础上更改或删掉我的API结构只有这三种情况:
所以,如果你的API不是很完美的话,可能也要更改代码