学习了一个下午的jsonp,记录一下以便以后翻阅。
jsonp原理就是动态插入脚本,就是$.getscript的封装版。
举例后台代码:
private string funone(string para,string callback) { return callback+"({\"code\": \"CA1998\",\"price\": 1780,\"tickets\": 5});"; }
前台代码
$.ajax({ type: "get", async: false, url: "http://localhost:2602/webone/controller.aspx?fnName=funone¶=para", dataType: "jsonp", //jsonp: "callback", //传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback) jsonpCallback: "flightHandler", //自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据 success: function (json) { alert(json); console.log(json); }, error: function () { alert('fail'); } });
1. datatype 要指定为jsonp,那样jquery里面会执行ajax方法会执行生成script的方法。
2. jsonp与jsoncallback,两个参数其实就是组成一个键值附件在url后面以get的方式传递,url+=“&jsonp=jsoncallback”
3. 然后jquery会生成一个全局的flightHandler变量
/*** jquery源码 ***/
// Handle JSONP-style loading
window[jsonp] = window[jsonp] || function (tmp) {
这里的jsonp就是flightHandler
然后会生成script标签,执行代码
最后执行
s.success.call(callbackContext, data, status, xhr);
s.success的作用链改到callbackcontext上,会把参数json复制给window[flightHandler]
然后会删除了window[flightHandler],见源码
window[jsonp] = window[jsonp] || function (tmp) { data = tmp; success(); //参数覆盖了jsoncallback complete(); // Garbage collect window[jsonp] = undefined; try { delete window[jsonp]; //删除了jsoncallback } catch (e) { } if (head) { head.removeChild(script); } };
最后,jsonp貌似不能用post提交,这个问题还有带解决一下。应该有办法的。
关于安全问题就呼之欲出了。
解决方案一:
客户端传两个值到服务器端:
一个是时间戳
new Date().getTime();
1362885228226如这个数
另外一个数是去时间戳的第3位和第5位数的和为:14.
服务器端以同样的算法进行验证,看看 第二个参数是不是时间戳的3位和5位的和。
相等就返回正确的,不想等就不是正常的客户端请求了。
然后把客户端的js代码压缩一下,防止破解。
其实这样也不是很完美,比较容易破解,不过总比什么都不做好。