Sencha Touch 2 Jsonp原理

JSONP是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)。

//Sencha Touch 2 Jsonp 核心源码
Ext.define('Ext.data.JsonP', {
alternateClassName: 'Ext.util.JSONP',

/* Begin Definitions */

singleton: true,


/* End Definitions */

/**
* Number of requests done so far.
* @private
*/
requestCount: 0,

/**
* Hash of pending requests.
* @private
*/
requests: {},

/**
* @property {Number} [timeout=30000]
* A default timeout (in milliseconds) for any JsonP requests. If the request has not completed in this time the failure callback will
* be fired.
*/
timeout: 30000,

/**
* @property {Boolean} disableCaching
* `true` to add a unique cache-buster param to requests.
*/
disableCaching: true,

/**
* @property {String} disableCachingParam
* Change the parameter which is sent went disabling caching through a cache buster.
*/
disableCachingParam: '_dc',

/**
* @property {String} callbackKey
* Specifies the GET parameter that will be sent to the server containing the function name to be executed when the
* request completes. Thus, a common request will be in the form of:
* `url?callback=Ext.data.JsonP.callback1`
*/
callbackKey: 'callback',

/**
* Makes a JSONP request.
* @param {Object} options An object which may contain the following properties. Note that options will take
* priority over any defaults that are specified in the class.
*
* @param {String} options.url The URL to request.
* @param {Object} [options.params] An object containing a series of key value pairs that will be sent along with the request.
* @param {Number} [options.timeout] See {@link #timeout}
* @param {String} [options.callbackKey] See {@link #callbackKey}
* @param {String} [options.callbackName] See {@link #callbackKey}
* The function name to use for this request. By default this name will be auto-generated: Ext.data.JsonP.callback1,
* Ext.data.JsonP.callback2, etc. Setting this option to "my_name" will force the function name to be
* Ext.data.JsonP.my_name. Use this if you want deterministic behavior, but be careful - the callbackName should be
* different in each JsonP request that you make.
* @param {Boolean} [options.disableCaching] See {@link #disableCaching}
* @param {String} [options.disableCachingParam] See {@link #disableCachingParam}
* @param {Function} [options.success] A function to execute if the request succeeds.
* @param {Function} [options.failure] A function to execute if the request fails.
* @param {Function} [options.callback] A function to execute when the request completes, whether it is a success or failure.
* @param {Object} [options.scope] The scope in which to execute the callbacks: The "this" object for the
* callback function. Defaults to the browser window.
*
* @return {Object} request An object containing the request details.
*/
request: function(options){
options = Ext.apply({}, options);

//<debug>
if (!options.url) {
Ext.Logger.error('A url must be specified for a JSONP request.');
}
//</debug>

var me = this,
disableCaching = Ext.isDefined(options.disableCaching) ? options.disableCaching : me.disableCaching,
cacheParam = options.disableCachingParam || me.disableCachingParam,
id = ++me.requestCount,
callbackName = options.callbackName || 'callback' + id,
callbackKey = options.callbackKey || me.callbackKey,
timeout = Ext.isDefined(options.timeout) ? options.timeout : me.timeout,
params = Ext.apply({}, options.params),
url = options.url,
name = Ext.isSandboxed ? Ext.getUniqueGlobalNamespace() : 'Ext',
request,
script;

params[callbackKey] = name + '.data.JsonP.' + callbackName;
if (disableCaching) {
params[cacheParam] = new Date().getTime();
}

script = me.createScript(url, params, options); //建立script标签实现跨域

me.requests[id] = request = {
url: url,
params: params,
script: script,
id: id,
scope: options.scope,
success: options.success,
failure: options.failure,
callback: options.callback,
callbackKey: callbackKey,
callbackName: callbackName
};

if (timeout > 0) {
request.timeout = setTimeout(Ext.bind(me.handleTimeout, me, [request]), timeout);
}

me.setupErrorHandling(request);
me[callbackName] = Ext.bind(me.handleResponse, me, [request], true);//
me.loadScript(request);
return request;
},

/**
* Abort a request. If the request parameter is not specified all open requests will be aborted.
* @param {Object/String} request The request to abort.
*/
abort: function(request){
var requests = this.requests,
key;

if (request) {
if (!request.id) {
request = requests[request];
}
this.handleAbort(request);
} else {
for (key in requests) {
if (requests.hasOwnProperty(key)) {
this.abort(requests[key]);
}
}
}
},

/**
* Sets up error handling for the script.
* @private
* @param {Object} request The request.
*/
setupErrorHandling: function(request){
request.script.onerror = Ext.bind(this.handleError, this, [request]);
},

/**
* Handles any aborts when loading the script.
* @private
* @param {Object} request The request.
*/
handleAbort: function(request){
request.errorType = 'abort';
this.handleResponse(null, request);
},

/**
* Handles any script errors when loading the script.
* @private
* @param {Object} request The request.
*/
handleError: function(request){
request.errorType = 'error';
this.handleResponse(null, request);
},

/**
* Cleans up any script handling errors.
* @private
* @param {Object} request The request.
*/
cleanupErrorHandling: function(request){
request.script.onerror = null;
},

/**
* Handle any script timeouts.
* @private
* @param {Object} request The request.
*/
handleTimeout: function(request){
request.errorType = 'timeout';
this.handleResponse(null, request);
},

/**
* Handle a successful response
* @private
* @param {Object} result The result from the request
* @param {Object} request The request
*/
handleResponse: function(result, request){
var success = true;

if (request.timeout) {
clearTimeout(request.timeout);
}

delete this[request.callbackName];
delete this.requests[request.id];

this.cleanupErrorHandling(request);
Ext.fly(request.script).destroy();
//数据响应返回
if (request.errorType) {
success = false;
Ext.callback(request.failure, request.scope, [request.errorType, request]);
} else {
Ext.callback(request.success, request.scope, [result, request]);
}
Ext.callback(request.callback, request.scope, [success, result, request.errorType, request]);
},

/**
* Create the script tag given the specified url, params and options. The options
* parameter is passed to allow an override to access it.
* @private
* @param {String} url The url of the request
* @param {Object} params Any extra params to be sent
* @param {Object} options The object passed to {@link #request}.
*/
createScript: function(url, params, options) {
var script = document.createElement('script');
script.setAttribute("src", Ext.urlAppend(url, Ext.Object.toQueryString(params)));
script.setAttribute("async", true);
script.setAttribute("type", "text/javascript");
return script;
},

/**
* Loads the script for the given request by appending it to the HEAD element. This is
* its own method so that users can override it (as well as {@link #createScript}).
* @private
* @param request The request object.
*/
loadScript: function (request) {
Ext.getHead().appendChild(request.script);//装载 来自服务器端的js
}
});


所以 服务端要这样写

boolean jsonP = false;
String cb = request.getParameter("callback"); //
传过来的 callback 参数 假如 Ext.data.JsonP.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 + "("); //这拼一下js 数据
}
out.print(dataBlock.toJsonString());
if (jsonP) {
out.write(");");
}


然后可以在页面上 输出
Ext.data.JsonP.callback({你的json 数据});
然后 主页面 script标签 加入这个 服务端的js, 实现跨域获取服务端数据
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值