Skip to content

Instantly share code, notes, and snippets.

@mscalora
Created May 5, 2019 05:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mscalora/4b19b608c99cbb5043fb5b8cdd9bb7b4 to your computer and use it in GitHub Desktop.
Save mscalora/4b19b608c99cbb5043fb5b8cdd9bb7b4 to your computer and use it in GitHub Desktop.
const encs = {json: 'application/json', text: 'text/plain', url: 'application/x-www-form-urlencoded', form: 'multipart/form-data'},
xhrRequestDefaults = {method: 'POST', encoding: 'url', beforeCallback: function () {}, openedCallback: function () {}};
/**
* Make http request to url with object data as body
* @param {string} url
* @param {(object | string)} [data] - post data, formatting controlled by encoding
* @param {object} [options] - object of options
* @param {string} [options.encoding] - body encoding 'none', 'url', 'form', 'json', 'text' or mime (content) type, default: 'url'
* @param {string} [options.contentType] - override automatic contentType, null disable automatic without sending one
* @param {function} [options.method] - 'GET', 'POST', 'PUT', etc, default: 'POST'
* @param {function} [options.beforeCallback] - callback before open(), params passed are (xhr, options)
* @param {function} [options.openedCallback] - callback just after open(), params passed are (xhr, options)
* @returns {Promise.<{ProgressEvent} event>}
*/
module.xhrRequest = function (url, data, options) {
const opts = Object.assign({}, xhrRequestDefaults, options || {}),
xhr = new XMLHttpRequest(),
enc = encs[opts.encoding] && opts.encoding || false, // false: custom content type
body = data === undefined || enc === 'no-body' ? null : enc === 'form' ? new FormData() :
enc === 'url' ? new URLSearchParams(data).toString() :
typeof data === 'object' ? JSON.stringify(data) : data,
contType = body === null ? null : enc && encs[enc] || opts.encoding;
if (enc === 'form') {
for (const key of Object.keys(data)) {
body.append(key, data[key]);
}
}
return new RSVP.Promise(function (resolve, reject) {
xhr.addEventListener('load', function () { this.options = opts; resolve(this); });
xhr.addEventListener('error', function () { this.options = opts; reject(this); });
for (const event of Object.keys(opts.events || {})) {
xhr.addEventListener(event, opts.events[event]);
}
opts.beforeCallback(xhr, opts);
xhr.open(opts.method, url);
opts.openedCallback(xhr, opts);
if (opts.contentType !== null && (opts.contentType || contType)) {
xhr.setRequestHeader('Content-Type', opts.contentType || contType);
}
for (const headerPair of opts.headers || []) {
xhr.setRequestHeader(headerPair[0], headerPair[1]);
}
xhr.send(body);
});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment