天天看点

JSONP跨域原理及示例

同源策略下,服务器不能请求该服务器以外的资源,及不能跨域请求。何为跨域,简单说就是协议+主机名+端口号(存在的话)三者之一不同就可称之为跨域。如:

1.http: //www.test.com 和 https: //www.test.com 之间协议不同,存在跨域

2.blog.csdn.net 和 blog.csdn.net:8080 之间端口号不同

3.write.csdn.net 和 blog.csdn.net 之间主机名不同

但是,如果需要进行跨域请求资源时怎么办呢?目前常用的方法有JSONP和CROS两种方法(本篇博文主要写一些JSONP相关的东西)。JSONP的原理是什么呢?html标签中存在一些如img、script等标签球可以通过src属性进行资源的请求。JSONP就是通过script标签来进行跨域资源的请求的。当发起JSONP请求的时候,服务器就会返回一段js脚本,请求方通过返回的该段脚本就可以获得请求的资源了。

举个栗子:

如:http://localhost:8080/webcontent/test.html页面存在

一个 http 😕/localhost:8888/jsonp/test?callback=Test 的请求,那么服务器就会返回Test({“test”:“this is json”})的字符串,该字符串可看做是一个名为Test的function,其参数为一个json object。当调用方得到该字符串时就会自动执行Test方法,来进行后续的处理。

代码如下:

调用方的JS代码

<script>
    function Test(i) {// 该方法会在结果返回时被自动调用
        console.log(i.test);
        console.log(JSON.stringify(i));
    }
</script>
<script src="http://127.0.0.1:8888/SpringmvcDemo/jsonp/msg?callBack=Test"></script>
           

服务器端代码:

@Controller
@RequestMapping("/jsonp")
public class JsonpTestController {
	
	@ResponseBody
	@RequestMapping("/msg")
	public String responseJsonp(HttpServletRequest request,
			@RequestParam String callBack) {
		String testJson = "{\"test\":\"this is json\"}";
		String jsonp = callBack + "(" + testJson + ");";
		
		return jsonp;
	}
}
           

若直接请求服务器,会返回如下结果

JSONP跨域原理及示例

JSONP跨域请求返回的结果(开发者工具控制台)

JSONP跨域原理及示例

通过以上演示可以看出,jsonp其实就是json外面包裹一个回调函数,通过该回掉函数就可以对json信息进行后续的处理解析。

在实际项目中通常使用JQUERY进行JSONP调用

示例代码:

$.ajax({
        async:false,
        type:'get',
        url: 'http://127.0.0.1:8888/SpringmvcDemo/jsonp/msg',
        cache : false,
        dataType: "jsonp",
        success: function(data) {
            // 进行相应处理
        },
        error: function(XMLHttpRequest, textStatus, errorThrown) {
            alert(errorThrown);
        }
    });
           
JSONP跨域原理及示例

JQUERY会在请求的Url后面加上callback=动态生成的回调函数名,服务器返回的数据就是生成的动态回调函数包裹json。JQUERY会默认使用callback,当然也可以指定callback为其他值,也可以指定回调函数名。

JSONP很方便的解决了跨域问题,但是由于本身只能采用get方式进行请求,所以在请求参数过多的情况下就无法使用了。

继续阅读