UNPKG

playable.js

Version:

A lightweight HTML5 game engine.

133 lines (117 loc) 3.32 kB
import {Event} from '../event/Event'; import {EventEmitter} from '../event/EventEmitter'; export class Request extends EventEmitter { protected $xhr: XMLHttpRequest = new XMLHttpRequest(); public constructor(options: RequestOption); public constructor(url: string, options?: RequestOption); public constructor(url?: string | RequestOption, options?: RequestOption) { super(); let method; let headers; let data; let responseType; let xhr = this.$xhr; if (url instanceof Object) { options = url; url = options.url; } if (options) { url = options.url || url; method = options.method || 'get'; headers = options.headers; data = options.data; responseType = options.responseType; } if (data instanceof Object) { let contentType = Request.$getContentType(headers); if (method.toLowerCase() === 'get') { let qs = Request.$getQueryString(data); url += url.indexOf('?') < 0 ? '?' + qs : '&' + qs; } else if (contentType === 'application/x-www-form-urlencoded') { data = Request.$getQueryString(data); } else if (contentType === 'application/json') { data = JSON.stringify(data); } } xhr.open(method || 'get', url); xhr.responseType = responseType; if (headers) { Object.keys(headers).forEach(key => { xhr.setRequestHeader(key, headers[key]); }); } xhr.addEventListener('abort', this.$onAbort.bind(this)); xhr.addEventListener('progress', this.$onProgress.bind(this)); xhr.addEventListener('readystatechange', this.$onReadyStateChange.bind(this)); xhr.send(data); } public get status(): number { return this.$xhr.status; } public get response(): any { return this.$xhr.response; } public get responseHeaders(): Object { let headers = {}; let str = this.$xhr.getAllResponseHeaders(); let arr = str.split('\n'); for (let header of arr) { let index = header.indexOf(':'); let key = header.slice(0, index).trim(); let value = header.slice(index + 1).trim(); if (headers[key]) { if (!Array.isArray(headers[key])) { headers[key] = [headers[key]]; } headers[key].push(value); } else if (key) { headers[key] = value; } } return headers; } public abort(): void { this.$xhr.abort(); } protected $onAbort(): void { this.emit(Event.ABORT); } protected $onProgress(e: ProgressEvent): void { if (e.lengthComputable) { let event = Event.create(Event.PROGRESS, e.loaded / e.total); this.emit(event); event.release(); } } protected $onReadyStateChange(e: Event): void { let xhr = this.$xhr; if (xhr.readyState === 4) { if (xhr.status >= 400 || xhr.status === 0) { this.emit(Event.ERROR, e); } else { let event = Event.create(Event.LOAD, xhr.response); this.emit(event); event.release(); } this.emit(Event.COMPLETE); } } protected static $getContentType(headers: Object): string { for (let key in headers) { if (key.toLowerCase() === 'content-type') { return headers[key].toLowerCase(); } } return null; } protected static $getQueryString(data: Object): string { return Object.keys(data).map(key => key + '=' + data[key]).join('&'); } } export interface RequestOption { url?: string, method?: string, headers?: object, responseType?: XMLHttpRequestResponseType, data?: any }