JsonP.html 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5. <title>The source code</title>
  6. <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
  7. <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
  8. <style type="text/css">
  9. .highlight { display: block; background-color: #ddd; }
  10. </style>
  11. <script type="text/javascript">
  12. function highlight() {
  13. document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
  14. }
  15. </script>
  16. </head>
  17. <body onload="prettyPrint(); highlight();">
  18. <pre class="prettyprint lang-js"><span id='Ext-data-JsonP'>/**
  19. </span> * @class Ext.data.JsonP
  20. * @singleton
  21. * This class is used to create JSONP requests. JSONP is a mechanism that allows for making
  22. * requests for data cross domain. More information is available &lt;a href=&quot;http://en.wikipedia.org/wiki/JSONP&quot;&gt;here&lt;/a&gt;.
  23. */
  24. Ext.define('Ext.data.JsonP', {
  25. /* Begin Definitions */
  26. singleton: true,
  27. /* End Definitions */
  28. <span id='Ext-data-JsonP-property-requestCount'> /**
  29. </span> * Number of requests done so far.
  30. * @private
  31. */
  32. requestCount: 0,
  33. <span id='Ext-data-JsonP-property-requests'> /**
  34. </span> * Hash of pending requests.
  35. * @private
  36. */
  37. requests: {},
  38. <span id='Ext-data-JsonP-property-timeout'> /**
  39. </span> * @property timeout
  40. * @type Number
  41. * A default timeout for any JsonP requests. If the request has not completed in this time the
  42. * failure callback will be fired. The timeout is in ms. Defaults to &lt;tt&gt;30000&lt;/tt&gt;.
  43. */
  44. timeout: 30000,
  45. <span id='Ext-data-JsonP-property-disableCaching'> /**
  46. </span> * @property disableCaching
  47. * @type Boolean
  48. * True to add a unique cache-buster param to requests. Defaults to &lt;tt&gt;true&lt;/tt&gt;.
  49. */
  50. disableCaching: true,
  51. <span id='Ext-data-JsonP-property-disableCachingParam'> /**
  52. </span> * @property disableCachingParam
  53. * @type String
  54. * Change the parameter which is sent went disabling caching through a cache buster. Defaults to &lt;tt&gt;'_dc'&lt;/tt&gt;.
  55. */
  56. disableCachingParam: '_dc',
  57. <span id='Ext-data-JsonP-property-callbackKey'> /**
  58. </span> * @property callbackKey
  59. * @type String
  60. * Specifies the GET parameter that will be sent to the server containing the function name to be executed when
  61. * the request completes. Defaults to &lt;tt&gt;callback&lt;/tt&gt;. Thus, a common request will be in the form of
  62. * url?callback=Ext.data.JsonP.callback1
  63. */
  64. callbackKey: 'callback',
  65. <span id='Ext-data-JsonP-method-request'> /**
  66. </span> * Makes a JSONP request.
  67. * @param {Object} options An object which may contain the following properties. Note that options will
  68. * take priority over any defaults that are specified in the class.
  69. * &lt;ul&gt;
  70. * &lt;li&gt;&lt;b&gt;url&lt;/b&gt; : String &lt;div class=&quot;sub-desc&quot;&gt;The URL to request.&lt;/div&gt;&lt;/li&gt;
  71. * &lt;li&gt;&lt;b&gt;params&lt;/b&gt; : Object (Optional)&lt;div class=&quot;sub-desc&quot;&gt;An object containing a series of
  72. * key value pairs that will be sent along with the request.&lt;/div&gt;&lt;/li&gt;
  73. * &lt;li&gt;&lt;b&gt;timeout&lt;/b&gt; : Number (Optional) &lt;div class=&quot;sub-desc&quot;&gt;See {@link #timeout}&lt;/div&gt;&lt;/li&gt;
  74. * &lt;li&gt;&lt;b&gt;callbackKey&lt;/b&gt; : String (Optional) &lt;div class=&quot;sub-desc&quot;&gt;See {@link #callbackKey}&lt;/div&gt;&lt;/li&gt;
  75. * &lt;li&gt;&lt;b&gt;callbackName&lt;/b&gt; : String (Optional) &lt;div class=&quot;sub-desc&quot;&gt;The function name to use for this request.
  76. * By default this name will be auto-generated: Ext.data.JsonP.callback1, Ext.data.JsonP.callback2, etc.
  77. * Setting this option to &quot;my_name&quot; will force the function name to be Ext.data.JsonP.my_name.
  78. * Use this if you want deterministic behavior, but be careful - the callbackName should be different
  79. * in each JsonP request that you make.&lt;/div&gt;&lt;/li&gt;
  80. * &lt;li&gt;&lt;b&gt;disableCaching&lt;/b&gt; : Boolean (Optional) &lt;div class=&quot;sub-desc&quot;&gt;See {@link #disableCaching}&lt;/div&gt;&lt;/li&gt;
  81. * &lt;li&gt;&lt;b&gt;disableCachingParam&lt;/b&gt; : String (Optional) &lt;div class=&quot;sub-desc&quot;&gt;See {@link #disableCachingParam}&lt;/div&gt;&lt;/li&gt;
  82. * &lt;li&gt;&lt;b&gt;success&lt;/b&gt; : Function (Optional) &lt;div class=&quot;sub-desc&quot;&gt;A function to execute if the request succeeds.&lt;/div&gt;&lt;/li&gt;
  83. * &lt;li&gt;&lt;b&gt;failure&lt;/b&gt; : Function (Optional) &lt;div class=&quot;sub-desc&quot;&gt;A function to execute if the request fails.&lt;/div&gt;&lt;/li&gt;
  84. * &lt;li&gt;&lt;b&gt;callback&lt;/b&gt; : Function (Optional) &lt;div class=&quot;sub-desc&quot;&gt;A function to execute when the request
  85. * completes, whether it is a success or failure.&lt;/div&gt;&lt;/li&gt;
  86. * &lt;li&gt;&lt;b&gt;scope&lt;/b&gt; : Object (Optional)&lt;div class=&quot;sub-desc&quot;&gt;The scope in
  87. * which to execute the callbacks: The &quot;this&quot; object for the callback function. Defaults to the browser window.&lt;/div&gt;&lt;/li&gt;
  88. * &lt;/ul&gt;
  89. * @return {Object} request An object containing the request details.
  90. */
  91. request: function(options){
  92. options = Ext.apply({}, options);
  93. //&lt;debug&gt;
  94. if (!options.url) {
  95. Ext.Error.raise('A url must be specified for a JSONP request.');
  96. }
  97. //&lt;/debug&gt;
  98. var me = this,
  99. disableCaching = Ext.isDefined(options.disableCaching) ? options.disableCaching : me.disableCaching,
  100. cacheParam = options.disableCachingParam || me.disableCachingParam,
  101. id = ++me.requestCount,
  102. callbackName = options.callbackName || 'callback' + id,
  103. callbackKey = options.callbackKey || me.callbackKey,
  104. timeout = Ext.isDefined(options.timeout) ? options.timeout : me.timeout,
  105. params = Ext.apply({}, options.params),
  106. url = options.url,
  107. name = Ext.name,
  108. request,
  109. script;
  110. params[callbackKey] = name + '.data.JsonP.' + callbackName;
  111. if (disableCaching) {
  112. params[cacheParam] = new Date().getTime();
  113. }
  114. script = me.createScript(url, params, options);
  115. me.requests[id] = request = {
  116. url: url,
  117. params: params,
  118. script: script,
  119. id: id,
  120. scope: options.scope,
  121. success: options.success,
  122. failure: options.failure,
  123. callback: options.callback,
  124. callbackKey: callbackKey,
  125. callbackName: callbackName
  126. };
  127. if (timeout &gt; 0) {
  128. request.timeout = setTimeout(Ext.bind(me.handleTimeout, me, [request]), timeout);
  129. }
  130. me.setupErrorHandling(request);
  131. me[callbackName] = Ext.bind(me.handleResponse, me, [request], true);
  132. me.loadScript(request);
  133. return request;
  134. },
  135. <span id='Ext-data-JsonP-method-abort'> /**
  136. </span> * Abort a request. If the request parameter is not specified all open requests will
  137. * be aborted.
  138. * @param {Object/String} request (Optional) The request to abort
  139. */
  140. abort: function(request){
  141. var me = this,
  142. requests = me.requests,
  143. key;
  144. if (request) {
  145. if (!request.id) {
  146. request = requests[request];
  147. }
  148. me.handleAbort(request);
  149. } else {
  150. for (key in requests) {
  151. if (requests.hasOwnProperty(key)) {
  152. me.abort(requests[key]);
  153. }
  154. }
  155. }
  156. },
  157. <span id='Ext-data-JsonP-method-setupErrorHandling'> /**
  158. </span> * Sets up error handling for the script
  159. * @private
  160. * @param {Object} request The request
  161. */
  162. setupErrorHandling: function(request){
  163. request.script.onerror = Ext.bind(this.handleError, this, [request]);
  164. },
  165. <span id='Ext-data-JsonP-method-handleAbort'> /**
  166. </span> * Handles any aborts when loading the script
  167. * @private
  168. * @param {Object} request The request
  169. */
  170. handleAbort: function(request){
  171. request.errorType = 'abort';
  172. this.handleResponse(null, request);
  173. },
  174. <span id='Ext-data-JsonP-method-handleError'> /**
  175. </span> * Handles any script errors when loading the script
  176. * @private
  177. * @param {Object} request The request
  178. */
  179. handleError: function(request){
  180. request.errorType = 'error';
  181. this.handleResponse(null, request);
  182. },
  183. <span id='Ext-data-JsonP-method-cleanupErrorHandling'> /**
  184. </span> * Cleans up anu script handling errors
  185. * @private
  186. * @param {Object} request The request
  187. */
  188. cleanupErrorHandling: function(request){
  189. request.script.onerror = null;
  190. },
  191. <span id='Ext-data-JsonP-method-handleTimeout'> /**
  192. </span> * Handle any script timeouts
  193. * @private
  194. * @param {Object} request The request
  195. */
  196. handleTimeout: function(request){
  197. request.errorType = 'timeout';
  198. this.handleResponse(null, request);
  199. },
  200. <span id='Ext-data-JsonP-method-handleResponse'> /**
  201. </span> * Handle a successful response
  202. * @private
  203. * @param {Object} result The result from the request
  204. * @param {Object} request The request
  205. */
  206. handleResponse: function(result, request){
  207. var success = true;
  208. if (request.timeout) {
  209. clearTimeout(request.timeout);
  210. }
  211. delete this[request.callbackName];
  212. delete this.requests[request.id];
  213. this.cleanupErrorHandling(request);
  214. Ext.fly(request.script).remove();
  215. if (request.errorType) {
  216. success = false;
  217. Ext.callback(request.failure, request.scope, [request.errorType]);
  218. } else {
  219. Ext.callback(request.success, request.scope, [result]);
  220. }
  221. Ext.callback(request.callback, request.scope, [success, result, request.errorType]);
  222. },
  223. <span id='Ext-data-JsonP-method-createScript'> /**
  224. </span> * Create the script tag given the specified url, params and options. The options
  225. * parameter is passed to allow an override to access it.
  226. * @private
  227. * @param {String} url The url of the request
  228. * @param {Object} params Any extra params to be sent
  229. * @param {Object} options The object passed to {@link #request}.
  230. */
  231. createScript: function(url, params, options) {
  232. var script = document.createElement('script');
  233. script.setAttribute(&quot;src&quot;, Ext.urlAppend(url, Ext.Object.toQueryString(params)));
  234. script.setAttribute(&quot;async&quot;, true);
  235. script.setAttribute(&quot;type&quot;, &quot;text/javascript&quot;);
  236. return script;
  237. },
  238. <span id='Ext-data-JsonP-method-loadScript'> /**
  239. </span> * Loads the script for the given request by appending it to the HEAD element. This is
  240. * its own method so that users can override it (as well as {@link #createScript}).
  241. * @private
  242. * @param request The request object.
  243. */
  244. loadScript: function (request) {
  245. Ext.getHead().appendChild(request.script);
  246. }
  247. });
  248. </pre>
  249. </body>
  250. </html>