UNPKG

frest

Version:

REST client for browser with Fetch

103 lines (86 loc) 2.72 kB
/** * @module frest * @hidden */ import { FrestRequest } from './types'; // These were taken from somewhere, made by someone. // I adopted it to frest but forgot to put any reference to original source. // If someone recognized these code and know where the original code came from, // please raise an issue so that I can put attribution here. const supportBlob = () => FileReader !== undefined && Blob !== undefined && (() => { try { // tslint:disable-next-line:no-unused-expression new Blob(); return true; } catch (error) { return false; } })(); function parseHeaders(rawHeaders: any) { const headers = new Headers(); // Replace instances of \r\n and \n followed by at least one space // or horizontal tab with a space // https://tools.ietf.org/html/rfc7230#section-3.2 const preProcessedHeaders = rawHeaders.replace(/\r?\n[\t ]+/g, ' '); preProcessedHeaders.split(/\r?\n/).forEach((line: any) => { const parts = line.split(':'); const key = parts.shift().trim(); if (key) { const value = parts.join(':').trim(); headers.append(key, value); } }); return headers; } function xhrFetch(url: string, conf: FrestRequest): Promise<Response> { return new Promise<Response>((resolve, reject) => { // const request = new Request(url, conf); const xhr = new XMLHttpRequest(); xhr.onload = () => { const options: any = { headers: parseHeaders(xhr.getAllResponseHeaders() || ''), status: xhr.status, statusText: xhr.statusText, }; options.url = 'responseURL' in xhr ? xhr.responseURL : options.headers.get('X-Request-URL'); const body = !conf.responseType || conf.responseType === 'text' ? xhr.responseText : xhr.response; resolve(new Response(body, options)); }; xhr.onerror = () => { reject(new TypeError('Network request failed')); }; xhr.ontimeout = () => { reject(new TypeError('Network request failed')); }; if (xhr.upload && conf.onUploadProgress) { xhr.upload.onprogress = conf.onUploadProgress; } if (conf.onDownloadProgress) { xhr.onprogress = conf.onDownloadProgress; } xhr.open(conf.method, url, true); if (conf.credentials === 'include') { xhr.withCredentials = true; } xhr.responseType = conf.responseType || 'text'; if (conf.action === 'download') { if (!conf.responseType && supportBlob()) { xhr.responseType = 'blob'; } } conf.headers.forEach((value, name) => { xhr.setRequestHeader(name, value); }); xhr.send(conf.body); }); } export default xhrFetch;