From 346c54a90fc27e4a4d196093ec1cfcdc46c00da7 Mon Sep 17 00:00:00 2001 From: Bowen Date: Wed, 20 Jun 2018 15:29:28 +0800 Subject: [PATCH] feat(core/Jsonp.js): handle 404/500 handle code 404/500, and then reject request promise --- README.md | 4 +-- dist/better-jsonp.common.js | 72 +++++++++++++++++++------------------ dist/better-jsonp.js | 72 +++++++++++++++++++------------------ dist/better-jsonp.min.js | 4 +-- lib/core/Jsonp.js | 48 +++++++++++++++---------- lib/jsonp.js | 13 ++----- samples/client.js | 18 +++++----- samples/test-page.html | 4 +-- 8 files changed, 125 insertions(+), 110 deletions(-) diff --git a/README.md b/README.md index 5108456..6d5773e 100644 --- a/README.md +++ b/README.md @@ -22,8 +22,8 @@ yarn add better-jsonp ``` ```html - - + + ``` ## Promise polyfill diff --git a/dist/better-jsonp.common.js b/dist/better-jsonp.common.js index ad7f0c4..05db59b 100644 --- a/dist/better-jsonp.common.js +++ b/dist/better-jsonp.common.js @@ -1,5 +1,5 @@ /*! - * better-jsonp v1.0.2 + * better-jsonp v1.1.0 * Copyrights (c) 2018 Bowen (lbwa) * Released under the MIT License. */ @@ -51,20 +51,28 @@ var defaultOptions = { }; var Jsonp = function () { - function Jsonp() { + function Jsonp(options) { classCallCheck(this, Jsonp); + + this.checkOptions(options); + + this.initState(options); + + this.encodeURL(options.url); + + this.insertToElement(this._request); } createClass(Jsonp, [{ key: 'checkOptions', value: function checkOptions(options) { - if (!options.url) throw new Error('Please check your request url.'); + if (!options || !options.url) throw new Error('Please check your request url.'); this.options = options; } }, { - key: 'generateJsonpCallback', - value: function generateJsonpCallback(options) { + key: 'genJsonpCallback', + value: function genJsonpCallback(options) { if (options.jsonpCallback) { this._jsonpCallback = options.jsonpCallback; } else { @@ -86,6 +94,12 @@ var Jsonp = function () { * 2. use arrow function to define `this` object value (Jsonp instance). */ return new Promise(function (resolve, reject) { + // handle 404/500 in response + _this._insertScript.onerror = function () { + _this.cleanScript(); + reject(new Error('Countdown has been clear! JSONP request unsuccessfully due to 404/500')); + }; + window[_this._jsonpCallback] = function (data) { _this.cleanScript(); resolve(data); @@ -93,14 +107,14 @@ var Jsonp = function () { }); } }, { - key: 'generateTimer', - value: function generateTimer(options) { + key: 'genTimer', + value: function genTimer(options) { var _this2 = this; // limit request period var timeout = options.timeout || defaultOptions.timeout; - // use arrow function to define `this` object value. + // use arrow function to define `this` object value (Jsonp instance). if (timeout) { this._timer = setTimeout(function () { window[_this2._jsonpCallback] = noop; @@ -110,6 +124,12 @@ var Jsonp = function () { }, timeout); } } + }, { + key: 'genScript', + value: function genScript() { + this._target = document.getElementsByTagName('script')[0] || document.body.lastElementChild; + this._insertScript = document.createElement('script'); + } }, { key: 'initState', value: function initState(options) { @@ -119,14 +139,16 @@ var Jsonp = function () { defineEnumerable(this, '_insertScript', null); defineEnumerable(this, '_target', null); + this.genScript(); + // set this._jsonpCallback - this.generateJsonpCallback(options); + this.genJsonpCallback(options); // invoke defineGlobalCallback after setting this._jsonpCallback defineEnumerable(this, '_globalCallback', this.defineGlobalCallback()); // set timer for limit request time - this.generateTimer(options); + this.genTimer(options); } }, { key: 'encodeURL', @@ -147,23 +169,13 @@ var Jsonp = function () { this._request = url; } + + // activate JSONP + }, { key: 'insertToElement', value: function insertToElement(url) { - var _this3 = this; - - this._target = document.getElementsByTagName('script')[0] || document.body.lastElementChild; - - this._insertScript = document.createElement('script'); this._insertScript.src = url; - - // listening 404/500 - this._insertScript.onerror = function () { - _this3.cleanScript(); - throw new Error('Countdown has been clear! JSONP request unsuccessfully due to 404/500'); - }; - - // activate JSONP this._target.parentNode.insertBefore(this._insertScript, this._target); } }, { @@ -175,7 +187,6 @@ var Jsonp = function () { } window[this._jsonpCallback] = noop; - if (this._timer) clearTimeout(this._timer); } }]); @@ -185,17 +196,10 @@ var Jsonp = function () { // facade in facade pattern // same as axios, zepto function createInstance(options) { - var jsonp = new Jsonp(); - - jsonp.checkOptions(options); - - jsonp.initState(options); - - jsonp.encodeURL(jsonp.options.url); - - jsonp.insertToElement(jsonp._request); + var jsonp = new Jsonp(options); - return jsonp._globalCallback; // from initState(options) + // from initState(options) + return jsonp._globalCallback; } module.exports = createInstance; diff --git a/dist/better-jsonp.js b/dist/better-jsonp.js index 6109955..920094c 100644 --- a/dist/better-jsonp.js +++ b/dist/better-jsonp.js @@ -1,5 +1,5 @@ /*! - * better-jsonp v1.0.2 + * better-jsonp v1.1.0 * Copyrights (c) 2018 Bowen (lbwa) * Released under the MIT License. */ @@ -55,20 +55,28 @@ }; var Jsonp = function () { - function Jsonp() { + function Jsonp(options) { classCallCheck(this, Jsonp); + + this.checkOptions(options); + + this.initState(options); + + this.encodeURL(options.url); + + this.insertToElement(this._request); } createClass(Jsonp, [{ key: 'checkOptions', value: function checkOptions(options) { - if (!options.url) throw new Error('Please check your request url.'); + if (!options || !options.url) throw new Error('Please check your request url.'); this.options = options; } }, { - key: 'generateJsonpCallback', - value: function generateJsonpCallback(options) { + key: 'genJsonpCallback', + value: function genJsonpCallback(options) { if (options.jsonpCallback) { this._jsonpCallback = options.jsonpCallback; } else { @@ -90,6 +98,12 @@ * 2. use arrow function to define `this` object value (Jsonp instance). */ return new Promise(function (resolve, reject) { + // handle 404/500 in response + _this._insertScript.onerror = function () { + _this.cleanScript(); + reject(new Error('Countdown has been clear! JSONP request unsuccessfully due to 404/500')); + }; + window[_this._jsonpCallback] = function (data) { _this.cleanScript(); resolve(data); @@ -97,14 +111,14 @@ }); } }, { - key: 'generateTimer', - value: function generateTimer(options) { + key: 'genTimer', + value: function genTimer(options) { var _this2 = this; // limit request period var timeout = options.timeout || defaultOptions.timeout; - // use arrow function to define `this` object value. + // use arrow function to define `this` object value (Jsonp instance). if (timeout) { this._timer = setTimeout(function () { window[_this2._jsonpCallback] = noop; @@ -114,6 +128,12 @@ }, timeout); } } + }, { + key: 'genScript', + value: function genScript() { + this._target = document.getElementsByTagName('script')[0] || document.body.lastElementChild; + this._insertScript = document.createElement('script'); + } }, { key: 'initState', value: function initState(options) { @@ -123,14 +143,16 @@ defineEnumerable(this, '_insertScript', null); defineEnumerable(this, '_target', null); + this.genScript(); + // set this._jsonpCallback - this.generateJsonpCallback(options); + this.genJsonpCallback(options); // invoke defineGlobalCallback after setting this._jsonpCallback defineEnumerable(this, '_globalCallback', this.defineGlobalCallback()); // set timer for limit request time - this.generateTimer(options); + this.genTimer(options); } }, { key: 'encodeURL', @@ -151,23 +173,13 @@ this._request = url; } + + // activate JSONP + }, { key: 'insertToElement', value: function insertToElement(url) { - var _this3 = this; - - this._target = document.getElementsByTagName('script')[0] || document.body.lastElementChild; - - this._insertScript = document.createElement('script'); this._insertScript.src = url; - - // listening 404/500 - this._insertScript.onerror = function () { - _this3.cleanScript(); - throw new Error('Countdown has been clear! JSONP request unsuccessfully due to 404/500'); - }; - - // activate JSONP this._target.parentNode.insertBefore(this._insertScript, this._target); } }, { @@ -179,7 +191,6 @@ } window[this._jsonpCallback] = noop; - if (this._timer) clearTimeout(this._timer); } }]); @@ -189,17 +200,10 @@ // facade in facade pattern // same as axios, zepto function createInstance(options) { - var jsonp = new Jsonp(); - - jsonp.checkOptions(options); - - jsonp.initState(options); - - jsonp.encodeURL(jsonp.options.url); - - jsonp.insertToElement(jsonp._request); + var jsonp = new Jsonp(options); - return jsonp._globalCallback; // from initState(options) + // from initState(options) + return jsonp._globalCallback; } return createInstance; diff --git a/dist/better-jsonp.min.js b/dist/better-jsonp.min.js index 1f888d6..95c2ad2 100644 --- a/dist/better-jsonp.min.js +++ b/dist/better-jsonp.min.js @@ -1,6 +1,6 @@ /*! - * better-jsonp v1.0.2 + * better-jsonp v1.1.0 * Copyrights (c) 2018 Bowen (lbwa) * Released under the MIT License. */ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.jsonp=t()}(this,function(){"use strict";function e(){}function t(e,t,n){Reflect.defineProperty(e,t,{enumerable:!1,writable:!0,value:n})}function n(e){return encodeURIComponent(e)}var i=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},r=function(){function e(e,t){for(var n=0;n { + // handle 404/500 in response + this._insertScript.onerror = () => { + this.cleanScript() + reject(new Error(`Countdown has been clear! JSONP request unsuccessfully due to 404/500`)) + } + window[this._jsonpCallback] = (data) => { this.cleanScript() resolve(data) @@ -40,11 +56,11 @@ export default class Jsonp { }) } - generateTimer (options) { + genTimer (options) { // limit request period const timeout = options.timeout || defaultOptions.timeout - // use arrow function to define `this` object value. + // use arrow function to define `this` object value (Jsonp instance). if (timeout) { this._timer = setTimeout(() => { window[this._jsonpCallback] = noop @@ -55,6 +71,11 @@ export default class Jsonp { } } + genScript () { + this._target = document.getElementsByTagName('script')[0] || document.body.lastElementChild + this._insertScript = document.createElement('script') + } + initState (options) { defineEnumerable(this, '_timer', null) defineEnumerable(this, '_request', null) @@ -62,14 +83,16 @@ export default class Jsonp { defineEnumerable(this, '_insertScript', null) defineEnumerable(this, '_target', null) + this.genScript() + // set this._jsonpCallback - this.generateJsonpCallback(options) + this.genJsonpCallback(options) // invoke defineGlobalCallback after setting this._jsonpCallback defineEnumerable(this, '_globalCallback', this.defineGlobalCallback()) // set timer for limit request time - this.generateTimer(options) + this.genTimer(options) } encodeURL (url) { @@ -90,19 +113,9 @@ export default class Jsonp { this._request = url } + // activate JSONP insertToElement (url) { - this._target = document.getElementsByTagName('script')[0] || document.body.lastElementChild - - this._insertScript = document.createElement('script') this._insertScript.src = url - - // listening 404/500 - this._insertScript.onerror = () => { - this.cleanScript() - throw new Error(`Countdown has been clear! JSONP request unsuccessfully due to 404/500`) - } - - // activate JSONP this._target.parentNode.insertBefore(this._insertScript, this._target) } @@ -113,7 +126,6 @@ export default class Jsonp { } window[this._jsonpCallback] = noop - if (this._timer) clearTimeout(this._timer) } } diff --git a/lib/jsonp.js b/lib/jsonp.js index 63f000c..71a5c82 100644 --- a/lib/jsonp.js +++ b/lib/jsonp.js @@ -3,17 +3,10 @@ import Jsonp from './core/Jsonp' // facade in facade pattern // same as axios, zepto function createInstance (options) { - const jsonp = new Jsonp() + const jsonp = new Jsonp(options) - jsonp.checkOptions(options) - - jsonp.initState(options) - - jsonp.encodeURL(jsonp.options.url) - - jsonp.insertToElement(jsonp._request) - - return jsonp._globalCallback // from initState(options) + // from initState(options) + return jsonp._globalCallback } export default createInstance diff --git a/samples/client.js b/samples/client.js index d114919..6829d40 100644 --- a/samples/client.js +++ b/samples/client.js @@ -2,18 +2,20 @@ import jsonp from './jsonp.js' const $ = document.getElementsByClassName.bind(document) const $$ = document.getElementById.bind(document) +const c = document.createElement.bind(document) +const js = JSON.stringify.bind(JSON) const app = $$('app') const jsonpBtn = $('btn')[0] const wrongRequestBtn = $('404')[0] const wrongBtn = $('500')[0] -const url = $('input-box')[0].value -function fn (data) { - console.log('Response data :', data) +function logger (data, isErr) { + const log = isErr ? console.error : console.log + log('Response data :', data) - const target = document.createElement('p') - target.innerText = JSON.stringify(data) + const target = c('p') + target.innerText = js(data) app.appendChild(target) } @@ -25,12 +27,12 @@ function generateInstance (url) { urlParams: { platform: 'desktop' } - }).then(data => fn(data)) - .catch(err => console.error(err)) + }).then(data => logger(data, false)) + .catch(err => logger(err, true)) } jsonpBtn.addEventListener('click', () => { - generateInstance(url) + generateInstance($('input-box')[0].value) }) wrongRequestBtn.addEventListener('click', () => { diff --git a/samples/test-page.html b/samples/test-page.html index b0951ca..bef6111 100644 --- a/samples/test-page.html +++ b/samples/test-page.html @@ -23,13 +23,13 @@

JSONP test

- Input your request url or use default url: + Input your request url or use default url: +

Tips: You can check your console drawer to find more details.

-

Tips: You can check your console drawer to find more details.