1.先说说普通的异步请求,获取json响应
假设两个web应用A,B. B 有个url地址 http://b.com/sys/menu/getMenuList.do 可以访问.在A的页面内要发异步请求访问B的URL,此时形成跨域。
$.ajax({
type: "get",
url: "http://b.com/sys/menu/getMenuList.do",
dataType: "json",
async: false,
success: function(data) {
alert("普通ajax ok")
},
error: function(xhr){
alert("普通ajax failed");
}
});
若B没有跨域限制,网上其他人的博客说get是可以跨域的。实际中由于B不是本人开发,不知道服务端如何实现,本人遇到的是能读取到响应码200,不能读取响应内容。
2.于是采取jsonp方式跨域
$.ajax({
async:false,
url: 'http://b.com/sys/menu/getMenuList.do', // 跨域URL
type: 'GET',
dataType: 'jsonp',
jsonp: 'jsoncallback',
beforeSend: function(){
},
success: function (json) {
alert("jsonp ok")
},
complete: function(XMLHttpRequest, textStatus){
},
error: function(xhr){
alert("jsonp failed");
}
});
注意两点:dataType: 'jsonp', jsonp: 'jsoncallback',
然后服务端响应函数类似这样
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//处理逻辑代码........
String callback = req.getParameter("jsoncallback");
resp.getWriter().write(callback + "({name:'tzy',phone:'123'})"); //参数为json格式
}
关键在与加粗两行代码,
后台返回前台的时候取出jsoncallback回调函数名,将json格式的数据作为函数的参数,整个以字符串的形式返回给前台。简单的说,普通json返回的是字符串
“{name: 'tzy', phone: '123'}”,而jsonp返回的是“functionA( {name: 'tzy', phone: '123'} )”这样一个内容是一个函数的字符串。函数名+括号+原先要返回的json做参数。(此处假设页面上异步请求发送的jsoncallback参数值是 functionA,实际上不需要使用者关心这个参数的值,jquery随机自动生成,发送给服务器,服务器回写后又自动调用该字符串形式的函数)
例如此例中可以在firebug 网络中看到实际请求为http://b.com/sys/menu/getMenuList.do?&jsoncallback=jsonp随机数字&_=随机数字
3.js几条实践指南
1. use === instead of ==
===会检查类型 0 === ‘0’为假, == 只检查值 0==‘0’为真
2. 不要使用 eval 慢,不安全。类型转换有对应内置函数,使用最精确的parse函数即可。
3. 任何时候都要 成对的花括号, 即使只有一条语句。if (a) { alert(a); }花括号必须坚持。类似的保持习惯,每个语句后写分号。
4. 可以把引入的js文件 放在页面最底部引入,提高页面加载速度。<script ........ src="......xxx.js"></script>等放在页面底部。
5. 不要再循环里面重复声明变量,放在循环外。
6. var obj = {}; instead of var obj = new Object(); 前者更快
类似的
var a = new Array();
a[0] = "Joe";
a[1] = 'Plumber';
不如 var a = ['Joe','Plumber']; 快
7. 循环 尽量 使用 for in 语句
8. 自动执行的函数 写成这样:
(function doSomething() {
return {
name: 'jeff',
lastName: 'way'
};
})();
不会函数重名冲突,更安全