最近做了一个项目,想在一个静态网页中直接请求外部服务器中的接口,实现数据共享,但是我当时忽略了一个问题,那就是跨域的问题。因为之前一直没有处理过这样的问题,就掉进这个坑中了。不过我还是很兴奋,早晚都是要掉进这个坑的,那么早掉进去比晚掉进去更加有意义。自己查了很多是资料都市写的不是很通俗易懂。也踩了不少的雷。现在吧我的解决方式和理解献下:
1、{"readyState":4,"status":200,"statusText":"load"}
ajax使用jsonp跨域调用webservice error错误信息"readyState":4,"status":200,"statusText":"success"
参考解析:https://blog.csdn.net/sinat_20846487/article/details/51782547
$.ajax({
type: 'GET',
url: 'http://192.168.0.164:8080/downloadurl/downloadurlOfUrlForJsonp',
dataType: 'jsonp', // 请求方式为jsonp
jsonp: "callback", // 自定义回调函数名
async: false, //是否异步
success: function (json) { //成功的回调函数\
alert(JSON.stringify(json));
},
error: function (data) {
alert("error:"+JSON.stringify(data));
}
});
结果进入erro:但是输出的报错信息为:“{"readyState":4,"status":200,"statusText":"success"}"
原因是webservice 返回的数据不是正确的jsonp格式
或者同一个webservice中处理多个jsonq请求,且jsonCallback都缺省
此时使用String callbackFunName=context.Request["jsapicallback"];
... context.Response.Write(callbackFunName + rdata);的方式 ,无法正确获取带有callback方法名的jsonp对象,所以jsonpCallback尽量不要省略
注意:
即使是使用jsonp 来处理跨域的时候也要严格的按照jsonp 的格式来进行处理。不然会出现是请求成功,但是会执行到Erro中,而不是执行到了success中去。
前端:
$.ajax({
type: 'GET',
url: 'http://192.168.0.164:8080/downloadurl/downloadurlOfUrlForJsonp',
dataType: 'jsonp', // 请求方式为jsonp
jsonpCallback:"successCallback",// 自定义回调函数名
async: false, //是否异步
success: function (json) { //成功的回调函数\
$("#android").attr("href",json.android);
$("#ios").attr("href",json.ios);
},
error: function (data) {
alert("error:"+JSON.stringify(data));
}
});
说明:
1、前端的请求方式必须是GET,jsonP是暂时不支持POST方式的
2、请求方式必须是jsonp
3、jsonpCallback:后端返回的json结果集的名字,也是后端返回的回调函数名后端返回的数据的固定格式:
successCallback({"android":"http://ylzxdown.oss-cn-shenzhen.aliyuncs.com/apk/ylzxsc.apk","ios":"https://fir.im/auy8"})
4、successCallback 是必须要和前端的 jsonpCallback:"successCallback",// 自定义回调函数名
相对应。
5、 jsonp:'jsoncallback',//自定义参数名称(这个参数是可要可不要的)
且必须要加上括号,因为是一个函数
说说后端:
@RequestMapping("/downloadurlOfUrlForJsonp")
public void downloadurlOfUrlForJsonp(HttpServletRequest req, HttpServletResponse rps) {
Map
List
if (ToolUtil.isNotEmpty(list)) {
map = list.stream().collect(Collectors.toMap(Downloadurl::getUrlname, Downloadurl::getUrl));
}
try {
rps.getWriter().print("successCallback(" + JSONObject.parseObject(JSON.toJSONString(map)).toString() + ")");
} catch (Exception e) {
e.printStackTrace();
}
}
1、世界返回的json格式数据不能是满足jsonp的数据需求, 需要是用流的形式将数据输出
2、数据装配的格式必须是满足josnp的数据需求