我记得面试的时候,面试官问我:jsonp的原理是什么?支持get或者post请求吗?
这个场景十分尴尬,因为我确实没有去了解过。。。
文章部分内容来源于:《深入浅出JSONP–解决ajax跨域问题》
前期储备知识:
同源策略,它是由Netscape提出的一个著名的安全策略。现在所有支持JavaScript 的浏览器都会使用这个策略。所谓同源是指,域名,协议,端口相同。
当一个浏览器的两个tab页中分别打开来 百度和谷歌的页面当一个百度浏览器执行一个脚本的时候会检查这个脚本是属于哪个页面的,即检查是否同源,只有和百度同源的脚本才会被执行。
所有支持Javascript的浏览器都会使用同源策略这个安全策略。
而解决这种同源策略的方法称之为跨域
跨域的方法有很多种,这里介绍一下最经典的jsonp跨域
JSONP和JSON好像啊,他们之间有什么联系吗?
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。对于JSON大家应该是很了解了吧,不是很清楚的朋友可以去json.org上了解下,简单易懂。
JSONP是JSON with Padding的略称。它是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)。–来源百度
JSONP就像是JSON+Padding一样(Padding这里我们理解为填充)
1. JSONP的由来
根据浏览器同源策略
,所谓同源就是协议、主机、端口号
都相同时成为同源。a 域的js不能直接访问 b域名的信息,但是script 标签的src属性可以跨域引用文件,jsonp是请求之后后台包装好一段json,并且把数据放在一个callback函数,返回一个js文件,动态引入这个文件,下载完成js之后,会去调用这个callback,通过这样访问数据。
2. JSONP有什么用
由于同源从略的限制,XMLHttpRequest
只允许请求前源(域名、协议、端口)的资源,为了实现跨域请求,可以通过script标签实现跨域请求,然后再服务端输出JSON数据并执行回调函数,从而解决跨域数据请求
3. JSONP原理
首先在客户端注册一个callback
,然后把callback
的名字传给服务器。此时,服务器先生成json数据,然后以javascript
语法的方式,生成function
,function
名字就是传递上来I带参数jsonp
。最后将json
数据直接以入参的方式,放置function
中,这样就生成js语法的文档
,返回给客户端。客户端浏览器,解析script变迁,并执行返回javascript文档,此时数据作为参数,传入了客户端预先定义好的callback函数里。简单的说,就是利用script标签没有跨域限制的“漏洞”来达到与第三方通讯的目的
。
json 是一种数据格式,jsonp 是一种数据调用的方式,带callback的json就是jsonp
JSONP具体实现:参考文章
前端代码在域www.practice.com下面,使用ajax发送了一个跨域的get请求
<!DOCTYPE html>
<html>
<head>
<title>GoJSONP</title>
</head>
<body>
<script type="text/javascript">
function jsonhandle(data){
alert("age:" + data.age + "name:" + data.name);
}
</script>
<script type="text/javascript" src="jquery-1.8.3.min.js">
</script>
<script type="text/javascript">
$(document).ready(function(){
$.ajax({
type : "get",
async: false,
url : "http://www.practice-zhao.com/student.php?id=1",
type: "json",
success : function(data) {
jsonhandle(data);
}
});
});
</script>
</body>
</html>
后端PHP代码放在域www.practice-zhao.com
下,简单的输出一段json
格式的数据
jsonhandle({
"age" : 15,
"name": "John",
})
当访问前端代码http://www.practice.com/gojsonp/index.html
时 chrome报以下错误
提示了不同源的URL禁止访问
jsonp支持post吗
因为它是利用动态创建script标签
,利用其src属性获取数据
,就和地址栏中的url意思一样
,所以只支持get方法
, 不支持post方法