vue-jsonp.umd.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. ;(function(root, factory) {
  2. if (typeof define === 'function' && define.amd) {
  3. define([], factory);
  4. } else if (typeof exports === 'object') {
  5. module.exports = factory();
  6. } else {
  7. root.vueJsonp = factory();
  8. }
  9. }(this, function() {
  10. /**
  11. * Vue Jsonp By LancerComet at 16:35, 2016.10.17.
  12. * # Carry Your World #
  13. *
  14. * @author: LancerComet
  15. * @license: MIT
  16. */
  17. var _timeout = null
  18. var vueJsonp = {
  19. install: function (Vue, options) {
  20. Vue.jsonp = jsonp
  21. Vue.prototype.$jsonp = jsonp
  22. if (typeof options === 'number') {
  23. _timeout = options
  24. }
  25. }
  26. }
  27. /**
  28. * JSONP function.
  29. * @param { String } url Target URL address.
  30. * @param { Object } params Querying params object.
  31. * @param { Number } timeout Timeout setting (ms).
  32. *
  33. * @example
  34. * Vue.jsonp('/url', {
  35. * callbackQuery: ''
  36. * callbackName: '',
  37. * name: 'LancerComet',
  38. * age: 26
  39. * }, 1000)
  40. */
  41. function jsonp (url, params, timeout) {
  42. params = params || {}
  43. timeout = timeout || _timeout
  44. return new Promise(function (resolve, reject) {
  45. if (typeof url !== 'string') {
  46. throw new Error('[Vue.jsonp] Type of param "url" is not string.')
  47. }
  48. var callbackQuery = params.callbackQuery || 'callback'
  49. var callbackName = params.callbackName || 'jsonp_' + randomStr()
  50. params[callbackQuery] = callbackName
  51. // Remove callbackQuery and callbackName.
  52. delete params.callbackQuery
  53. delete params.callbackName
  54. // Convert params to querying str.
  55. var queryStrs = []
  56. Object.keys(params).forEach(function (queryName) {
  57. queryStrs = queryStrs.concat(formatParams(queryName, params[queryName]))
  58. })
  59. var queryStr = flatten(queryStrs).join('&')
  60. // Timeout timer.
  61. var timeoutTimer = null
  62. // Setup timeout.
  63. if (typeof timeout === 'number') {
  64. timeoutTimer = setTimeout(function () {
  65. removeErrorListener()
  66. headNode.removeChild(paddingScript)
  67. delete window[callbackName]
  68. reject({ statusText: 'Request Timeout', status: 408 })
  69. }, timeout)
  70. }
  71. // Create global function.
  72. window[callbackName] = function (json) {
  73. clearTimeout(timeoutTimer)
  74. removeErrorListener()
  75. headNode.removeChild(paddingScript)
  76. resolve(json)
  77. delete window[callbackName]
  78. }
  79. // Create script element.
  80. var headNode = document.querySelector('head')
  81. var paddingScript = document.createElement('script')
  82. // Add error listener.
  83. paddingScript.addEventListener('error', onError)
  84. // Append to head element.
  85. paddingScript.src = url + (/\?/.test(url) ? '&' : '?') + queryStr
  86. headNode.appendChild(paddingScript)
  87. /**
  88. * Padding script on-error event.
  89. * @param {Event} event
  90. */
  91. function onError (event) {
  92. removeErrorListener()
  93. clearTimeout(timeoutTimer)
  94. reject({
  95. status: 400,
  96. statusText: 'Bad Request'
  97. })
  98. }
  99. /**
  100. * Remove on-error event listener.
  101. */
  102. function removeErrorListener () {
  103. paddingScript.removeEventListener('error', onError)
  104. }
  105. })
  106. }
  107. /**
  108. * Generate random string.
  109. * @return { String }
  110. */
  111. function randomStr () {
  112. return (Math.floor(Math.random() * 100000) * Date.now()).toString(16)
  113. }
  114. /**
  115. * Format params into querying string.
  116. * @param {{}}
  117. * @return {string[]}
  118. */
  119. function formatParams (queryName, value) {
  120. queryName = queryName.replace(/=/g, '')
  121. var result = []
  122. switch (value.constructor) {
  123. case String:
  124. case Number:
  125. case Boolean:
  126. result.push(encodeURIComponent(queryName) + '=' + encodeURIComponent(value))
  127. break
  128. case Array:
  129. value.forEach(function (item) {
  130. result = result.concat(formatParams(queryName + '[]=', item))
  131. })
  132. break
  133. case Object:
  134. Object.keys(value).forEach(function (key) {
  135. var item = value[key]
  136. result = result.concat(formatParams(queryName + '[' + key + ']', item))
  137. })
  138. break
  139. }
  140. return result
  141. }
  142. /**
  143. * Flat querys.
  144. *
  145. * @param {any} array
  146. * @returns
  147. */
  148. function flatten (array) {
  149. var querys = []
  150. array.forEach(function (item) {
  151. if (typeof item === 'string') {
  152. querys.push(item)
  153. } else {
  154. querys = querys.concat(flatten(item))
  155. }
  156. })
  157. return querys
  158. }
  159. return vueJsonp;
  160. }));