ty-mobile-uni
Version:
uView UI,是uni-app生态优秀的UI框架,全面的组件和便捷的工具会让您信手拈来,如鱼得水
188 lines (160 loc) • 4.46 kB
JavaScript
;(function(root, factory) {
if (typeof define === 'function' && define.amd) {
define([], factory);
} else if (typeof exports === 'object') {
module.exports = factory();
} else {
root.vueJsonp = factory();
}
}(this, function() {
/**
* Vue Jsonp By LancerComet at 16:35, 2016.10.17.
* # Carry Your World #
*
* @author: LancerComet
* @license: MIT
*/
var _timeout = null
var vueJsonp = {
install: function (Vue, options) {
Vue.jsonp = jsonp
Vue.prototype.$jsonp = jsonp
if (typeof options === 'number') {
_timeout = options
}
}
}
/**
* JSONP function.
* @param { String } url Target URL address.
* @param { Object } params Querying params object.
* @param { Number } timeout Timeout setting (ms).
*
* @example
* Vue.jsonp('/url', {
* callbackQuery: ''
* callbackName: '',
* name: 'LancerComet',
* age: 26
* }, 1000)
*/
function jsonp (url, params, timeout) {
params = params || {}
timeout = timeout || _timeout
return new Promise(function (resolve, reject) {
if (typeof url !== 'string') {
throw new Error('[Vue.jsonp] Type of param "url" is not string.')
}
var callbackQuery = params.callbackQuery || 'callback'
var callbackName = params.callbackName || 'jsonp_' + randomStr()
params[callbackQuery] = callbackName
// Remove callbackQuery and callbackName.
delete params.callbackQuery
delete params.callbackName
// Convert params to querying str.
var queryStrs = []
Object.keys(params).forEach(function (queryName) {
queryStrs = queryStrs.concat(formatParams(queryName, params[queryName]))
})
var queryStr = flatten(queryStrs).join('&')
// Timeout timer.
var timeoutTimer = null
// Setup timeout.
if (typeof timeout === 'number') {
timeoutTimer = setTimeout(function () {
removeErrorListener()
headNode.removeChild(paddingScript)
delete window[callbackName]
reject({ statusText: 'Request Timeout', status: 408 })
}, timeout)
}
// Create global function.
window[callbackName] = function (json) {
clearTimeout(timeoutTimer)
removeErrorListener()
headNode.removeChild(paddingScript)
resolve(json)
delete window[callbackName]
}
// Create script element.
var headNode = document.querySelector('head')
var paddingScript = document.createElement('script')
// Add error listener.
paddingScript.addEventListener('error', onError)
// Append to head element.
paddingScript.src = url + (/\?/.test(url) ? '&' : '?') + queryStr
headNode.appendChild(paddingScript)
/**
* Padding script on-error event.
* @param {Event} event
*/
function onError (event) {
removeErrorListener()
clearTimeout(timeoutTimer)
reject({
status: 400,
statusText: 'Bad Request'
})
}
/**
* Remove on-error event listener.
*/
function removeErrorListener () {
paddingScript.removeEventListener('error', onError)
}
})
}
/**
* Generate random string.
* @return { String }
*/
function randomStr () {
return (Math.floor(Math.random() * 100000) * Date.now()).toString(16)
}
/**
* Format params into querying string.
* @param {{}}
* @return {string[]}
*/
function formatParams (queryName, value) {
queryName = queryName.replace(/=/g, '')
var result = []
switch (value.constructor) {
case String:
case Number:
case Boolean:
result.push(encodeURIComponent(queryName) + '=' + encodeURIComponent(value))
break
case Array:
value.forEach(function (item) {
result = result.concat(formatParams(queryName + '[]=', item))
})
break
case Object:
Object.keys(value).forEach(function (key) {
var item = value[key]
result = result.concat(formatParams(queryName + '[' + key + ']', item))
})
break
}
return result
}
/**
* Flat querys.
*
* @param {any} array
* @returns
*/
function flatten (array) {
var querys = []
array.forEach(function (item) {
if (typeof item === 'string') {
querys.push(item)
} else {
querys = querys.concat(flatten(item))
}
})
return querys
}
return vueJsonp;
}));