X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/0494b8d9b9bb03ab6c22b34dae81261e3cd7e3e6..7a654f8d43fdb43d78b63d90528bed6e86b608cc:/src/data/proxy/JsonP.js diff --git a/src/data/proxy/JsonP.js b/src/data/proxy/JsonP.js new file mode 100644 index 00000000..1f0ceed9 --- /dev/null +++ b/src/data/proxy/JsonP.js @@ -0,0 +1,335 @@ +/** + * @author Ed Spencer + * @class Ext.data.proxy.JsonP + * @extends Ext.data.proxy.Server + * + *
JsonPProxy is useful when you need to load data from a domain other than the one your application is running + * on. If your application is running on http://domainA.com it cannot use {@link Ext.data.proxy.Ajax Ajax} to load its + * data from http://domainB.com because cross-domain ajax requests are prohibited by the browser.
+ * + *We can get around this using a JsonPProxy. JsonPProxy injects a <script> tag into the DOM whenever + * an AJAX request would usually be made. Let's say we want to load data from http://domainB.com/users - the script tag + * that would be injected might look like this:
+ * +
+<script src="http://domainB.com/users?callback=someCallback"></script>
+
+ *
+ * When we inject the tag above, the browser makes a request to that url and includes the response as if it was any + * other type of JavaScript include. By passing a callback in the url above, we're telling domainB's server that we + * want to be notified when the result comes in and that it should call our callback function with the data it sends + * back. So long as the server formats the response to look like this, everything will work:
+ * +
+someCallback({
+ users: [
+ {
+ id: 1,
+ name: "Ed Spencer",
+ email: "ed@sencha.com"
+ }
+ ]
+});
+
+ *
+ * As soon as the script finishes loading, the 'someCallback' function that we passed in the url is called with the + * JSON object that the server returned.
+ * + *JsonPProxy takes care of all of this automatically. It formats the url you pass, adding the callback + * parameter automatically. It even creates a temporary callback function, waits for it to be called and then puts + * the data into the Proxy making it look just like you loaded it through a normal {@link Ext.data.proxy.Ajax AjaxProxy}. + * Here's how we might set that up:
+ * +
+Ext.define('User', {
+ extend: 'Ext.data.Model',
+ fields: ['id', 'name', 'email']
+});
+
+var store = new Ext.data.Store({
+ model: 'User',
+ proxy: {
+ type: 'jsonp',
+ url : 'http://domainB.com/users'
+ }
+});
+
+store.load();
+
+ *
+ * That's all we need to do - JsonPProxy takes care of the rest. In this case the Proxy will have injected a + * script tag like this: + * +
+<script src="http://domainB.com/users?callback=stcCallback001" id="stcScript001"></script>
+
+ *
+ * Customization
+ * + *Most parts of this script tag can be customized using the {@link #callbackParam}, {@link #callbackPrefix} and + * {@link #scriptIdPrefix} configurations. For example: + * +
+var store = new Ext.data.Store({
+ model: 'User',
+ proxy: {
+ type: 'jsonp',
+ url : 'http://domainB.com/users',
+ callbackParam: 'theCallbackFunction',
+ callbackPrefix: 'ABC',
+ scriptIdPrefix: 'injectedScript'
+ }
+});
+
+store.load();
+
+ *
+ * Would inject a script tag like this:
+ * +
+<script src="http://domainB.com/users?theCallbackFunction=ABC001" id="injectedScript001"></script>
+
+ *
+ * Implementing on the server side
+ * + *The remote server side needs to be configured to return data in this format. Here are suggestions for how you + * might achieve this using Java, PHP and ASP.net:
+ * + *Java:
+ * +
+boolean jsonP = false;
+String cb = request.getParameter("callback");
+if (cb != null) {
+ jsonP = true;
+ response.setContentType("text/javascript");
+} else {
+ response.setContentType("application/x-json");
+}
+Writer out = response.getWriter();
+if (jsonP) {
+ out.write(cb + "(");
+}
+out.print(dataBlock.toJsonString());
+if (jsonP) {
+ out.write(");");
+}
+
+ *
+ * PHP:
+ * +
+$callback = $_REQUEST['callback'];
+
+// Create the output object.
+$output = array('a' => 'Apple', 'b' => 'Banana');
+
+//start output
+if ($callback) {
+ header('Content-Type: text/javascript');
+ echo $callback . '(' . json_encode($output) . ');';
+} else {
+ header('Content-Type: application/x-json');
+ echo json_encode($output);
+}
+
+ *
+ * ASP.net:
+ * +
+String jsonString = "{success: true}";
+String cb = Request.Params.Get("callback");
+String responseString = "";
+if (!String.IsNullOrEmpty(cb)) {
+ responseString = cb + "(" + jsonString + ")";
+} else {
+ responseString = jsonString;
+}
+Response.Write(responseString);
+
+ *
+ */
+Ext.define('Ext.data.proxy.JsonP', {
+ extend: 'Ext.data.proxy.Server',
+ alternateClassName: 'Ext.data.ScriptTagProxy',
+ alias: ['proxy.jsonp', 'proxy.scripttag'],
+ requires: ['Ext.data.JsonP'],
+
+ defaultWriterType: 'base',
+
+ /**
+ * @cfg {String} callbackKey (Optional) See {@link Ext.data.JsonP#callbackKey}.
+ */
+ callbackKey : 'callback',
+
+ /**
+ * @cfg {String} recordParam
+ * The param name to use when passing records to the server (e.g. 'records=someEncodedRecordString').
+ * Defaults to 'records'
+ */
+ recordParam: 'records',
+
+ /**
+ * @cfg {Boolean} autoAppendParams True to automatically append the request's params to the generated url. Defaults to true
+ */
+ autoAppendParams: true,
+
+ constructor: function(){
+ this.addEvents(
+ /**
+ * @event exception
+ * Fires when the server returns an exception
+ * @param {Ext.data.proxy.Proxy} this
+ * @param {Ext.data.Request} request The request that was sent
+ * @param {Ext.data.Operation} operation The operation that triggered the request
+ */
+ 'exception'
+ );
+ this.callParent(arguments);
+ },
+
+ /**
+ * @private
+ * Performs the read request to the remote domain. JsonPProxy does not actually create an Ajax request,
+ * instead we write out a