Skip to content

Instantly share code, notes, and snippets.

@loveyunk
Created November 28, 2018 07:02
Show Gist options
  • Save loveyunk/f8f54d4ac49661b386bd00880947f4fd to your computer and use it in GitHub Desktop.
Save loveyunk/f8f54d4ac49661b386bd00880947f4fd to your computer and use it in GitHub Desktop.
// 参考:https://github.com/yanatan16/nanoajax
// Best place to find information on XHR features is:
// https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest
function ajax(params, callback) {
var reqfields = [
'responseType', 'withCredentials', 'timeout', 'onprogress'
];
// Simple and small ajax function
// Takes a parameters object and a callback function
// Parameters:
// - url: string, required
// - headers: object of `{header_name: header_value, ...}`
// - body:
// + string (sets content type to 'application/x-www-form-urlencoded' if not set in headers)
// + FormData (doesn't set content type so that browser will set as appropriate)
// - method: 'GET', 'POST', etc. Defaults to 'GET' or 'POST' based on body
//
// The following parameters are passed onto the xhr object.
// IMPORTANT NOTE: The caller is responsible for compatibility checking.
// - responseType: string, various compatability, see xhr docs for enum options
// - withCredentials: boolean, IE10+, CORS only
// - timeout: long, ms timeout, IE8+
// - onprogress: callback, IE10+
//
// Callback function prototype:
// - statusCode from request
// + Possibly null or 0 (i.e. falsy) if an error occurs
// - response
// + if responseType set and supported by browser, this is an object of some type (see docs)
// + otherwise if request completed, this is the string text of the response
// + if request is aborted, this is "Abort"
// + if request times out, this is "Timeout"
// + if request errors before completing (probably a CORS issue), this is "Error"
// - request object
//
// Returns the request object. So you can call .abort() or other methods
//
var headers = params.headers || {};
var body = params.body;
var method = params.method || (body ? 'POST' : 'GET');
var url = params.url;
var called = false;
function setDefault(obj, key, value) {
obj[key] = obj[key] || value;
}
var xhr = new XMLHttpRequest();
function cb(statusCode, responseText) {
return function () {
if (!called) {
callback(xhr.status === undefined ? statusCode : xhr.status,
xhr.status === 0 ? "Error" : (xhr.response || xhr.responseText || responseText),
xhr);
called = true;
}
}
}
xhr.open(method, url, true);
// 只要浏览器接收到服务器的响应,不管其状态如何,都会触发load事件。
// 这就意味着必须检查status属性,才能确定数据是否真的已经可用了。
var success = xhr.onload = cb(200);
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) success();
};
xhr.onerror = cb(null, 'Error'); // 在请求发生错误时触发
xhr.ontimeout = cb(null, 'Timeout'); // 请求超时时触发
xhr.onabort = cb(null, 'Abort'); // 在因为调用abort()方法而终止连接时触发
if (body) {
setDefault(headers, 'X-Requested-With', 'XMLHttpRequest');
if (!window.FormData || !(body instanceof window.FormData)) {
setDefault(headers, 'Content-Type', 'application/x-www-form-urlencoded');
}
}
for (var i = 0, len = reqfields.length, field; i < len; i++) {
field = reqfields[i];
if (params[field] !== undefined) {
xhr[field] = params[field];
}
}
for (var field in headers) {
xhr.setRequestHeader(field, headers[field]);
}
xhr.send(body);
return xhr;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment