场景:项目中我负责后台接口开发,接口提供给app端的开发人员。app端ajax远程请求服务器时会出现ajax跨域问题。由于我是第一次开发 以前也没碰到过。所以我又上网查了帖子,最后大致知道了实现方式。虽然不太了解原理。但是也解决了这个问题,所以记录一下,方便自己以后复习。
思路:ajax请求后台时,在dataType的属性写上'jsonp',然后增加一个新的属性:jsonp,属性值为任意字符(比如jsonpCallback),在后台
可以用这个字符名接到一个值,而这个值在后台数据返回的时候要用到。因为用jsonp返回数据时的格式和普通返回不一样。jsonp 返回数据的格式是要返回一个类似js函数的格式 但是没有{},而你要返回的数据就放在参数中,具体的格式是:函数名(后台要传输的数据),这里的函数名就是‘jsonpCallback’所接到的实际参数,后台传输的数据就是自己要返回的数据,比如ajax请求时,后台接到的‘jsonpCallback’的值是"1223541_js",你后台要返回你数据是个名叫dataList的集合。 然后 你可以后台拼接成上述格式 最终返回为这样格式的: 1223541_js(‘dataList’) ,就可以了。
注意:①为什么要用jsonp属性的传入后台参数的值做返回函数的函数名? :因为 每个ajax都会生成不同的随机字符,用随机字符做返回值,这样可以找到是哪个ajax发出的请求。
② ()里是要返回的参数,但必须拼接上单引号,使其作为变量参数回传。
前台ajax的格式如图:
上面是前台的请求格式,其实和普通的ajax没有区别,就是dataType值变成了jsonp,然后多了个属性:jsonp 属性值可以随便写。当ajax请求后台时,后台根据jsonp中的字符串名获取真正的值 然后拼接 再作返回。返回的值就在回调函数的参数中。然后就可以像普通ajax的操作一样了。
后台代码:
//代码不全还有许多注解没有加 但是不影响操作
public class TestJsonpAction{
//前台请求时进入的方法
public String getLogisticsStatusList () {
String jsonpCallback = getParameter("jsonpCallback");//接收ajax请求的参数。
……//接收的其他数据 还有其他处理的代码
List<Map> result = page.getResult();//后台要返回的数据
String resultDate = JSONObject.fromObject(results).toString();//将数据转成json格式(项目需要)
//由于每次都要拼接数据所以把拼接部分写成工具类,此处调用。(下方有工具类代码)
String callBackData= JsonUtil.getJsonCallBackString( resultDate , jsonpCallback);//调用工具类拼接成jspon需要的格式
Struts2Utils.renderJson( callBackData ); //最终返回前台的数据
}
}
拼接格式的工具类:
package com.nebula.app.app.common.utils;
public class JsonUtil {
/**
* @param str 要回传前台的数据
*
* @param jsonpCallback 前台接收的jsonp传递的值
*
* */
public static String getJsonCallBackString(String str ,String jsonpCallback){
if(jsonpCallback == null ||"".equals(jsonpCallback)){
return str;
}else{
return jsonpCallback+"('"+str+"')";
}
}
}
大神的博客 里面有专业的介绍