美文网首页
jsonp处理跨域

jsonp处理跨域

作者: 凯睿看世界 | 来源:发表于2019-06-12 10:37 被阅读0次

什么是跨域?
简单的来说,出于安全方面的考虑,页面中的JavaScript无法访问其他服务器上的数据,即“同源策略”。而跨域就是通过某些手段来绕过同源策略限制,实现不同服务器之间通信的效果。

具体策略限制情况可看下表:

image.png

什么是JSONP?
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,而JSONP(JSON with Padding)则是JSON 的一种“使用模式”,通过这种模式可以实现数据的跨域获取。

JSONP跨域的原理
在同源策略下,在某个服务器下的页面是无法获取到该服务器以外的数据的,但img、iframe、script等标签是个例外,这些标签可以通过src属性请求到其他服务器上的数据。利用script标签的开放策略,我们可以实现跨域请求数据,当然,也需要服务端的配合。当我们正常地请求一个JSON数据的时候,服务端返回的是一串JSON类型的数据,而我们使用JSONP模式来请求数据的时候,服务端返回的是一段可执行的JavaScript代码。

举个例子,假如需要从服务器(http://www.a.com/user?id=123)获取的数据如下:

{"id": 123, "name" : 张三, "age": 17}
那么,使用JSONP方式请求(http://www.a.com/user?id=123?callback=foo)的数据将会是如下:

foo({"id": 123, "name" : 张三, "age": 17});
当然,如果服务端考虑得更加充分,返回的数据可能如下:

try{foo({"id": 123, "name" : 张三, "age": 17});}catch(e){}
这时候我们只要定义一个foo()函数,并动态地创建一个script标签,使其的src属性为http://www.a.com/user?id=123?callback=foo

便可以使用foo函数来调用返回的数据了。

在jQuery中如何通过JSONP来跨域获取数据
第一种方法是在ajax函数中设置dataType为'jsonp':

$.ajax({
        dataType: 'jsonp',
        url: 'http://www.a.com/user?id=123',
        success: function(data){
                //处理data数据
        }
});

第二种方法是利用getJSON来实现,只要在地址中加上callback=?参数即可:

$.getJSON('http://www.a.com/user?id=123&callback=?', function(data){
        //处理data数据
});

也可以简单地使用getScript方法:

//此时也可以在函数外定义foo方法

function foo(data){
        //处理data数据
}
$.getJSON('http://www.a.com/user?id=123&callback=foo');

JSONP的应用
JSONP在开放API中可以起到非常重要的作用,开放API是运用在开发者自己的应用上,而许多应用往往是在开发者的服务器上而不是在新浪微博的服务器上,因此跨域请求数据成为开发者们所需要解决的一大问题,广大开放平台应该实现对JSONP的支持,这一点新浪微博开放平台便做的非常好(虽然某些API里没有说明,但实际上是可以使用JSONP方式调用的)。

1、页面请求

function complete(){

var data = {
"enterprise_id":"8316",
"receiver_name":"王敏", 
"province_code":"110000",
"city_code":"110100",
"district_code":"110102",
"province_name":"北京市",
"city_name":"市辖区",
"district_name":"西城区",
"address":"这里是详细地址",
"contact_phone":"18721703659",
"default_address":"0"
};
$.ajax({
url:"http://usermanage.yaoex.com:8080/enterpriseInfo/saveReceiverAddress",
data:data,
dataType :'JSONP',
jsonp: "callbackSaveAddress",
jsonpCallback:"success_jsonp",
contentType: "application/json;charset=utf-8",
success: function (data) {
console.info(data);
}
});
}

2、服务器响应

/**
* 新增收发货地址信息
* @return
* @throws Exception
* {"enterprise_id":"8316","receiver_name":"小小蔡芽", "province_code":"110000","city_code":"110100","district_code":"110102","province_name":"北京市","city_name":"市辖区","district_name":"西城区","address":"这里是详细地址","contact_phone":"18721703659","default_address":"0"}
*/
@RequestMapping(value = "/saveReceiverAddress")
@ResponseBody
public String saveReceiverAddress(HttpServletRequest request,@RequestBody UsermanageReceiverAddress usermanageReceiverAddress) {
String jsonpCallback = request.getParameter("callbackSaveAddress");
Map<String, Object> resp = new HashMap<String, Object>();
try {
//获取用户信息
User user = UsermanageUserUtil.getCurrentUser(request);
if (null == user) {
resp.put("result", "error");
resp.put("msg", " 未能正常获取登录用户信息!");
logger.info(" 未能正常获取登录用户信息!");
return jsonpCallback + "(" + JSONObject.toJSONString(resp) + ")";
}
usermanageReceiverAddress.setEnterprise_id(String.valueOf(user.getEnterprise_id()));
List<UsermanageReceiverAddress> usermanageReceiverAddressList= userManageEnterpriseService.queryReceiverAddress(String.valueOf(user.getEnterprise_id()));
if(null != usermanageReceiverAddressList && usermanageReceiverAddressList.size()>=10){
resp.put("result", "error");
resp.put("msg","添加失败,您只能保存10条收发货地址信息!");
logger.info("添加失败,您只能保存10条收发货地址信息!");
return jsonpCallback + "(" + JSONObject.toJSONString(resp) + ")";
}
//新增地址插入正式表
userManageEnterpriseService.saveAddress(usermanageReceiverAddress);
resp.put("result", "success");
resp.put("msg", "地址保存成功!");
return jsonpCallback + "(" + JSONObject.toJSONString(resp) + ")";
} catch (Exception e) {
logger.error(e.getMessage());
resp.put("result", "error");
resp.put("msg", "地址保存失败!");
return jsonpCallback + "(" + JSONObject.toJSONString(resp) + ")";
}
}
image.png

其他参考
接收页面传递过来的参数。参数就是方法的名称。返回一个json数据,需要把json数据包装成一句js代码。返回一个字符串。

参数:回调方法名称
返回值:字符串
方法一:自己包装返回方法

@Controller
public class ItemCatController {
        @Autowired
        private ItemCatService itemCatService;
 
        @RequestMapping(value="/itemcat/list", 
        produces=MediaType.APPLICATION_JSON_VALUE + ";charset=utf-8")
        @ResponseBody
        public String getItemCatList(String callback) {
        CatResult catResult = itemCatService.getItemCatList();
        //把pojo转换成字符串
        String json = JsonUtils.objectToJson(catResult);
        //拼装返回值
        String result = callback + "(" + json + ");";
        return result;
        }
}

方法二:用框架类MappingJacksonValue处理

@RequestMapping("/itemcat/list")
       @ResponseBody
       public Object getItemCatList(String callback) {
       CatResult catResult = itemCatService.getItemCatList();
       MappingJacksonValue mappingJacksonValue = new MappingJacksonValue(catResult);
       mappingJacksonValue.setJsonpFunction(callback);
       return mappingJacksonValue;
       }

参考:
https://www.cnblogs.com/xiaoxiaoccaiya/p/7088176.html
https://blog.csdn.net/pdsu161530247/article/details/82189866

相关文章

  • Axios跨域处理方案

    Ajax跨域问题使用jsonp处理 Axios跨域请求问题处理: 1、在config文件夹下的prod和dev的j...

  • Axios跨域处理方案

    Ajax跨域问题使用jsonp处理 Axios跨域请求问题处理: 1、在config文件夹下的prod和dev的j...

  • 对jsonp 的理解认识

    什么是跨域?为什么要跨域呢?听说jsonp能. 为什么jsonp能跨域呢?什么时候使用jsonp?怎么使用json...

  • 浏览器跨域问题,教你手写实现jsonp跨域

    跨域概述为什么会有跨域跨域解决办法:1、jsonp;2、后台代理手写实现jsonp跨域(包括服务器端代码) 跨域问...

  • ajax跨域请求

    ajax跨域请求(jsonp) 利用JSONP解决AJAX跨域问题的原理与jQuery解决方案JSONP jQue...

  • cookie和跨域数据交互(jsonp)

    cookie: 跨域数据交互(jsonp) 谁能跨域:JSONP/iframe-window.name/h5-PO...

  • jsonp处理跨域

    什么是跨域?简单的来说,出于安全方面的考虑,页面中的JavaScript无法访问其他服务器上的数据,即“同源策略”...

  • 复习jsonp和promise

    一.jsonp 1.jsonp是跨域访问api,ajax不能跨域 2.在vue中使用jsonp首先要安装jsonp...

  • 跨域

    本文介绍跨域的八种方法: JSONP只要说到跨域,就必须聊到 JSONP,JSONP全称为:JSON with P...

  • 常用前端面试问题

    跨域方法 Jsonp: 采用非同源限制标签进行处理请求,我理解的jsonp => json - page一个jso...

网友评论

      本文标题:jsonp处理跨域

      本文链接:https://www.haomeiwen.com/subject/lmdkfctx.html