项目需要在前台页面中,通过JQuery跨域调用Rest服务接口。
后台代码:
public class HeadAction extends BaseAction{
private HttpServletRequest request;
private HttpServletResponse response;
public void findSecondCat(){
ActionContext ctx = ActionContext.getContext();
request = (HttpServletRequest) ctx.get(ServletActionContext.HTTP_REQUEST);
response = (HttpServletResponse)ctx.get(ServletActionContext.HTTP_RESPONSE);
//response.setHeader("Cache-Control", "no-cache");
response.setContentType("text/json;charset=utf-8");
String catType = request.getParameter("catType");
List<CategoryNode> node = CategoryCache.getAllCategoryNodes(1, Integer.parseInt(catType));//调用缓存查询分类
try {
PrintWriter out = response.getWriter();
JSONArray ja = new JSONArray();
for(CategoryNode c: node){//返回json格式
JSONObject j = new JSONObject();
j.put("id", c.ID);
j.put("name", c.Name);
ja.add(j);
}
String cb = request.getParameter("callback");//若果是ajax请求会带这个参数 你可以firfox的firbug跟踪一下就看到了
if(cb != null){//如果是跨域
StringBuffer sb = new StringBuffer(cb);
sb.append("(");
sb.append(ja.toString());
sb.append(")");
out.write(sb.toString());
out.close();
}else{//不跨域的情况
out.write(ja.toString());
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
JQuery调用代码:
$.ajax( {
type : 'get',
url : '<%=com.utils.PubConstant.wwwDomain %>/index/findSecondCat.action',
data : {
catType : 1
},
dataType : 'jsonp',//跨域必须用jsonp
error : function() {
},
success : function(data) {
innerOption = "<option value=''>全部分类</option>";
for(var i=0;i<data.length;i++){
innerOption += '<option value="'+data[i].id+'">'+data[i].name+'</option>';
};
$('#secondCatIdId').html(innerOption);
$("#lang, #secondCatIdId").jListbox();
}
});
总结下JSONP原理:
首先在客户端注册一个callback, 然后把callback的名字传给服务器。
此时,服务器先生成 json 数据。
然后以 javascript 语法的方式,生成一个function , function 名字就是传递上来的参数 jsonp.
最后将 json 数据直接以入参的方式,放置到 function 中,这样就生成了一段 js 语法的文档,返回给客户端。
客户端浏览器,解析script标签,并执行返回的 javascript 文档,此时数据作为参数,传入到了客户端预先定义好的 callback 函数里.(动态执行回调函数)