UNPKG

phoenix

Version:

The official JavaScript client for the Phoenix web framework.

117 lines (103 loc) 3.54 kB
import { global, XHR_STATES } from "./constants" export default class Ajax { static request(method, endPoint, headers, body, timeout, ontimeout, callback){ if(global.XDomainRequest){ let req = new global.XDomainRequest() // IE8, IE9 return this.xdomainRequest(req, method, endPoint, body, timeout, ontimeout, callback) } else if(global.XMLHttpRequest){ let req = new global.XMLHttpRequest() // IE7+, Firefox, Chrome, Opera, Safari return this.xhrRequest(req, method, endPoint, headers, body, timeout, ontimeout, callback) } else if(global.fetch && global.AbortController){ // Fetch with AbortController for modern browsers return this.fetchRequest(method, endPoint, headers, body, timeout, ontimeout, callback) } else { throw new Error("No suitable XMLHttpRequest implementation found") } } static fetchRequest(method, endPoint, headers, body, timeout, ontimeout, callback){ let options = { method, headers, body, } let controller = null if(timeout){ controller = new AbortController() const _timeoutId = setTimeout(() => controller.abort(), timeout) options.signal = controller.signal } global.fetch(endPoint, options) .then(response => response.text()) .then(data => this.parseJSON(data)) .then(data => callback && callback(data)) .catch(err => { if(err.name === "AbortError" && ontimeout){ ontimeout() } else { callback && callback(null) } }) return controller } static xdomainRequest(req, method, endPoint, body, timeout, ontimeout, callback){ req.timeout = timeout req.open(method, endPoint) req.onload = () => { let response = this.parseJSON(req.responseText) callback && callback(response) } if(ontimeout){ req.ontimeout = ontimeout } // Work around bug in IE9 that requires an attached onprogress handler req.onprogress = () => { } req.send(body) return req } static xhrRequest(req, method, endPoint, headers, body, timeout, ontimeout, callback){ req.open(method, endPoint, true) req.timeout = timeout for(let [key, value] of Object.entries(headers)){ req.setRequestHeader(key, value) } req.onerror = () => callback && callback(null) req.onreadystatechange = () => { if(req.readyState === XHR_STATES.complete && callback){ let response = this.parseJSON(req.responseText) callback(response) } } if(ontimeout){ req.ontimeout = ontimeout } req.send(body) return req } static parseJSON(resp){ if(!resp || resp === ""){ return null } try { return JSON.parse(resp) } catch { console && console.log("failed to parse JSON response", resp) return null } } static serialize(obj, parentKey){ let queryStr = [] for(var key in obj){ if(!Object.prototype.hasOwnProperty.call(obj, key)){ continue } let paramKey = parentKey ? `${parentKey}[${key}]` : key let paramVal = obj[key] if(typeof paramVal === "object"){ queryStr.push(this.serialize(paramVal, paramKey)) } else { queryStr.push(encodeURIComponent(paramKey) + "=" + encodeURIComponent(paramVal)) } } return queryStr.join("&") } static appendParams(url, params){ if(Object.keys(params).length === 0){ return url } let prefix = url.match(/\?/) ? "&" : "?" return `${url}${prefix}${this.serialize(params)}` } }