JSONP的原理和使用

一、什么是JSONP

首先我们得先了解JSONP是怎么产生的。
最开始跨域请求数据没有现在方便,Ajax直接请求普通文件存在跨域无权限访问的问题,然后聪明的程序员想出了一套非官方的解决办法,程序员发现凡是带有“src”这个属性的标签都拥有跨域的能力,比如<·img>、<·iframe>、<·script>。
早期的程序员也是这么干的,最后程序员们发现最好的解决办法就是——动态创建script标签发起请求,然后从后端拿到请求回来的数据进行处理,再然后把刚刚创建的script标签删掉,这就是JSONP的整套流程。做完这一切,在用户的角度是感觉不到动态创建script标签以及发送请求的。
一句话来讲的话 JSONP(JSON with Padding)是JSON的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题。即可以让网页从别的网域要资料(跨域)。

二、JSONP的原理

ajax请求受同源策略影响,不允许进行跨域请求,而script标签src属性中的链接却可以访问跨域的js脚本,利用这个特性,服务端不再返回JSON格式的数据,而是返回一段调用某个函数的js代码,在src中进行了调用,这样实现了跨域。

同源策略即:同一协议,同一域名,同一端口号。当其中一个不满足时,我们的请求即会发生跨域问题。

JSONP的原理和使用_第1张图片
举几个简单例子:
1.http://www.abc.com:3000到https://www.abc.com:3000的请求会出现跨域(域名、端口相同但协议不同)
2.http://www.abc.com:3000到http://www.abc.com:3001的请求会出现跨域(域名、协议相同但端口不同)
3.http://www.abc.com:3000到http://www.def.com:3000的请求会出现跨域(域名不同)

而不管是script标签的src还是img标签的src,或者说link标签的href都没有被同源策略所限制。

三、JSONP跨域的实现

jsonp其实是由两部分组成的:回调函数和数据。回调函数是当响应到来时应该在页面中调用的函数,而数据就是传入回调函数中的json参数。利用的是script标签中src可以引用不同域上js文件的思想,进行跨域。
那么该如何做呢?接下来我们看一下jsonp的入门案例:

原生方式(配置繁琐 三大步)

1.利用javaScript中的src属性进行跨域!!!.

<!--该json一直保存到浏览器中等待调用,但是没有函数名称无法调用  -->
<script type="text/javascript" src="http://manager.jt.com/test.json"></script>

2.自定义回调函数

<script type="text/javascript">
		/*JS是解释执行的语言  */
		/*定义回调函数  */
		function hello(data){
     
			alert(data.name);
		}
</script>

3.将返回值的结果 进行特殊的格式封装!!!

hello({
     "id":"1","name":"我是谁,我在哪???"})

jQuery实现JSONP,像常规ajax调用一样的方便.(动态生成回调函数)

前端页面:

$.ajax({
     
			url:"http://manager.jt.com/web/testJSONP",
			type:"get",				//jsonp只能支持get请求   src只能进行get请求.
			dataType:"jsonp",       //dataType表示返回值类型 必须标识
			//jsonp: "callback",    //指定参数名称
			jsonpCallback: "hello",  //指定回调函数名称
			success:function (data){
        //data经过jQuery封装返回就是json串
				alert(data.itemId);
				alert(data.itemDesc);
			}
		});	

服务器处理跨域请求:

package com.jt.web.controller;

import com.fasterxml.jackson.databind.util.JSONPObject;
import com.jt.pojo.ItemDesc;
import com.jt.unit.ObjectMapperUtil;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController     //json字符串
public class JSONPController {
     

    /**
     * 完成JSONP的调用
     * url:http://manager.jt.com/web/testJSONP?callback=jQuery111101021758391465013_1597656788213&_=1597656788214
     * 规定:返回值结果,必须经过特殊的格式封装.callback(json)
     */
    @RequestMapping("/web/testJSONP")
    public JSONPObject jsonp(String callback){
     
        ItemDesc itemDesc = new ItemDesc();
        itemDesc.setItemId(101L).setItemDesc("我是商品详情信息");
        return new JSONPObject(callback, itemDesc);
    }

   /* public String  jsonp(String callback){
        ItemDesc itemDesc = new ItemDesc();
        itemDesc.setItemId(101L).setItemDesc("我是商品详情信息");
        String json = ObjectMapperUtil.toJSON(itemDesc);
        //return callback+"({'id':'100','name':'tomcat猫'})";
        return callback +"("+json+")";
    }*/

}

jsonp的优点:
它不像XHR对象实现ajax请求那样受到同源政策的限制,它的兼容性更好,XHR在进行ajax请求时,为了兼容IE,还需创建ActiveX对象。并且在请求完毕之后可以通过回调函数的方式将结果回传

jsonp的缺点:
它只支持get请求而不支持post等其它类型的HTTP请求;它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用问题

end~

你可能感兴趣的:(java)