UNPKG

3.66 kBJavaScriptView Raw
1(function (global, factory) {
2 if (typeof define === 'function' && define.amd) {
3 define(['exports', 'module'], factory);
4 } else if (typeof exports !== 'undefined' && typeof module !== 'undefined') {
5 factory(exports, module);
6 } else {
7 var mod = {
8 exports: {}
9 };
10 factory(mod.exports, mod);
11 global.fetchJsonp = mod.exports;
12 }
13})(this, function (exports, module) {
14 'use strict';
15
16 var defaultOptions = {
17 timeout: 5000,
18 jsonpCallback: 'callback',
19 jsonpCallbackFunction: null
20 };
21
22 function generateCallbackFunction() {
23 return 'jsonp_' + Date.now() + '_' + Math.ceil(Math.random() * 100000);
24 }
25
26 function clearFunction(functionName) {
27 // IE8 throws an exception when you try to delete a property on window
28 // http://stackoverflow.com/a/1824228/751089
29 try {
30 delete window[functionName];
31 } catch (e) {
32 window[functionName] = undefined;
33 }
34 }
35
36 function removeScript(scriptId) {
37 var script = document.getElementById(scriptId);
38 if (script) {
39 document.getElementsByTagName('head')[0].removeChild(script);
40 }
41 }
42
43 function fetchJsonp(_url) {
44 var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
45
46 // to avoid param reassign
47 var url = _url;
48 var timeout = options.timeout || defaultOptions.timeout;
49 var jsonpCallback = options.jsonpCallback || defaultOptions.jsonpCallback;
50
51 var timeoutId = undefined;
52
53 return new Promise(function (resolve, reject) {
54 var callbackFunction = options.jsonpCallbackFunction || generateCallbackFunction();
55 var scriptId = jsonpCallback + '_' + callbackFunction;
56
57 window[callbackFunction] = function (response) {
58 resolve({
59 ok: true,
60 // keep consistent with fetch API
61 json: function json() {
62 return Promise.resolve(response);
63 }
64 });
65
66 if (timeoutId) clearTimeout(timeoutId);
67
68 removeScript(scriptId);
69
70 clearFunction(callbackFunction);
71 };
72
73 // Check if the user set their own params, and if not add a ? to start a list of params
74 url += url.indexOf('?') === -1 ? '?' : '&';
75
76 var jsonpScript = document.createElement('script');
77 jsonpScript.setAttribute('src', '' + url + jsonpCallback + '=' + callbackFunction);
78 if (options.charset) {
79 jsonpScript.setAttribute('charset', options.charset);
80 }
81 if (options.nonce) {
82 jsonpScript.setAttribute('nonce', options.nonce);
83 }
84 jsonpScript.id = scriptId;
85 document.getElementsByTagName('head')[0].appendChild(jsonpScript);
86
87 timeoutId = setTimeout(function () {
88 reject(new Error('JSONP request to ' + _url + ' timed out'));
89
90 clearFunction(callbackFunction);
91 removeScript(scriptId);
92 window[callbackFunction] = function () {
93 clearFunction(callbackFunction);
94 };
95 }, timeout);
96
97 // Caught if got 404/500
98 jsonpScript.onerror = function () {
99 reject(new Error('JSONP request to ' + _url + ' failed'));
100
101 clearFunction(callbackFunction);
102 removeScript(scriptId);
103 if (timeoutId) clearTimeout(timeoutId);
104 };
105 });
106 }
107
108 // export as global function
109 /*
110 let local;
111 if (typeof global !== 'undefined') {
112 local = global;
113 } else if (typeof self !== 'undefined') {
114 local = self;
115 } else {
116 try {
117 local = Function('return this')();
118 } catch (e) {
119 throw new Error('polyfill failed because global object is unavailable in this environment');
120 }
121 }
122 local.fetchJsonp = fetchJsonp;
123 */
124
125 module.exports = fetchJsonp;
126});
\No newline at end of file