首頁 >web前端 >js教程 >ajax和jsonp以及json區別使用步驟詳解

ajax和jsonp以及json區別使用步驟詳解

php中世界最好的语言
php中世界最好的语言原創
2018-04-25 09:34:406308瀏覽

這次帶給大家ajax和jsonp以及json區別使用步驟詳解,ajax和jsonp以及json使用的注意事項有哪些,下面就是實戰案例,一起來看一下。

前言

  第一次聽到jsonp,其實早在2年之前。當時在做一個活動頁面的抽獎模組,要從服務端get一個機率,當時什麼都不懂,同事說用ajax,我就用ajax,同事說dataType改成jsonp,我就改成jsonp。於是乎活動頁面做完了,以後也沒有碰到過jsonp,在這段期間我一直以為jsonp跟ajax息息相關,是xhr的一種特殊的跨域形式...直到一個月前的一次面試,問到jsonp我被虐成狗,才決定看下jsonp,好吧,原來jsonp也不是很難。

為什麼要用jsonp?

  相信大家對跨域一定不陌生,對同源策略也同樣熟悉。什麼,你沒聽過?沒關係,既然是深入淺出,那就從頭說起。

  假如我寫了個index頁面,頁面裡有個請求,請求的是一個json資料(不知道json資料的猛戳JSON簡介以及用法匯總),簡單思考寫下如下程式碼:

<script src=&#39;http://libs.baidu.com/jquery/2.0.0/jquery.min.js&#39;></script>
<script type="text/javascript">
 $.ajax({
 url: 'http://localhost/a.json',
 dataType: "json",
 success: function (data) {
  console.log(data);
 }
 })
</script> 
{
 "name": "hanzichi",
 "age": 10
}

  樓主把兩個文件都放在wamp下的www資料夾下,ajax請求沒有跨域,完美得到結果:

  但是如果我的json檔案和index檔案不在一個域下,也就是跨域(不懂跨域的可參考JavaScript 的同源策略)了呢?

  試著在wamp下新開個apache連接埠(不知道怎麼開的可參考WampServer下使用多個連接埠存取權),將json檔案放到該服務連接埠的資料夾下(樓主設定的連接埠號為8080,預設的是80埠),試著發送請求: 

<script src=&#39;http://libs.baidu.com/jquery/2.0.0/jquery.min.js&#39;></script>
<script type="text/javascript">
 $.ajax({
 url: 'http://localhost:8080/a.json',
 dataType: "json",
 success: function (data) {
  console.log(data);
 }
 })
</script>

#  很顯然,提示跨域了!怎麼搞?這時jsonp就要出馬了!

神奇的script標籤

  與jsonp息息相關的是script標籤,而xhr或者說傳統意義上的ajax與之沒有半毛錢關係!

  接著看上面的index.html程式碼,我們看到頁面引用了百度cdn的jquery路徑,對於這樣的方式我們似乎已經習以為常,但是仔細一想,script標籤可是完完全全的跨域的啊...沒錯,jsonp的實作核心就是利用script標籤的跨域能力!於是我們靈機一動,似乎可以這麼搞,動態生成一個script標籤,把json的url賦值給script的src屬性,然後再把這個script標籤插入dom裡...

<body>
 <script src=&#39;http://libs.baidu.com/jquery/2.0.0/jquery.min.js&#39;></script>
 <script type="text/javascript">
 var s = document.createElement('script');
 s.src = 'http://localhost:8080/a.json';
 document.body.appendChild(s);
 </script>
</body>

  我們創建了一個script標籤,而標籤內包裹的內容正是需要的json數據,但是報錯如下:

 

  原因是因為json數據並不是合法的js語句,把上面的json資料放在一個回呼函數中是最簡單的方法:

<body>
 <script src=&#39;http://libs.baidu.com/jquery/2.0.0/jquery.min.js&#39;></script>
 <script type="text/javascript">
 function jsonpcallback(json) {
  console.log(json);
 }
 var s = document.createElement('script');
 s.src = 'http://localhost:8080/a.json';
 document.body.appendChild(s);
 </script>
</body> 
jsonpcallback({
 "name": "hanzichi",
 "age": 10
});

#  當然,這時的a.json檔案不一定要這樣命名,改成a.js也不會有一點問題。

  而如果是與服務端互動也是一樣的道理,例如和php:

<body>
 <script src=&#39;http://libs.baidu.com/jquery/2.0.0/jquery.min.js&#39;></script>
 <script type="text/javascript">
 function jsonpcallback(json) {
  console.log(json);
 }
 var s = document.createElement('script');
 s.src="http://localhost:8080/test.php?callback=jsonpcallback";
 document.body.appendChild(s);
 </script>
</body> 
<?php
 $jsondata = &#39;{
 "name": "hanzichi",
 "age": 10
 }&#39;;
 echo $_GET[&#39;callback&#39;].&#39;(&#39;.$jsondata.&#39;)&#39;;
?>

  而如果是與服務端互動也是一樣的道理,例如和php:

<script src=&#39;http://libs.baidu.com/jquery/2.0.0/jquery.min.js&#39;></script>
<script type="text/javascript">
 $.ajax({
 url: 'http://localhost:8080/a.json',
 dataType: 'jsonp',
 jsonpCallback: 'CallBack',
 success: function (data) {
  console.log(data);
 }
 });
</script> 
CallBack({
 "name": "hanzichi",
 "age": 10
});

  而如果是與服務端互動也是一樣的道理,例如和php:

<script src=&#39;http://libs.baidu.com/jquery/2.0.0/jquery.min.js&#39;></script>
<script type="text/javascript">
 $.ajax({
 url: 'http://localhost:8080/test.php',
 dataType: 'jsonp',
 success: function (data) {
  console.log(data);
 }
 });
</script> 
<?php
 $jsondata = &#39;{
 "name": "hanzichi",
 "age": 10
 }&#39;;
 echo $_GET[&#39;callback&#39;].&#39;(&#39;.$jsondata.&#39;)&#39;;
?>
  需要注意的是,jsonp提供的url(即動態產生的script標籤的src),無論看上去是什麼形式,最終產生回傳的都是一段js程式碼。

JQuery對jsonp的封裝

#  為了便於開發,jq對jsonp也進行了封裝,封裝在了ajax方法中。

// 1
$.getJSON("http://localhost:8080/test.php?callback=?", function(data) { 
 console.log(data);
});
// 2
$.get('http://localhost:8080/test.php', function(data) { 
 console.log(data);
}, 'jsonp');
###  以上程式碼是針對請求檔中寫死了callback函式名稱的情況。因為請求的是json文件,json不是伺服器端的動態語言不能進行解析,如果是php或其他的伺服器端語言,則不用寫死函數名,例如下面這樣:###rrreee###   當然類似的封裝好的方法還有幾種:###
// 1
$.getJSON("http://localhost:8080/test.php?callback=?", function(data) { 
 console.log(data);
});
// 2
$.get('http://localhost:8080/test.php', function(data) { 
 console.log(data);
}, 'jsonp');

  需要注意的是getJSON方法的请求地址url需要带上callback=?,因为jq对该方法进行封装的时候并没有默认回调函数变量名为callback,于是php中$_GET['callback']就找不到变量值了。

  而一般的jq方法url 中不用指定 callback 参数。对于 jQuery 中的 jsonp 来说,callback 参数是自动添加的。默认情况下,jQuery 生成的 jsonp 请求中 callback 参数是形如 callback=jQuery200023559735575690866_1434954892929 这种根据看似随机的名字,对应的就是 success 那个处理函数,所以一般不用特意处理。二如果要写死callback名的话,可以参照上文。

 

总结

  由于同源策略的限制,XmlHttpRequest只允许请求当前源(域名、协议、端口)的资源,为了实现跨域请求,可以通过script标签实现跨域请求,然后在服务端输出JSON数据并执行回调函数,从而解决了跨域的数据请求,这就是jsonp的核心。

  jsonp原理:

 1.首先在客户端注册一个callback, 然后把callback的名字传给服务器。
 2.服务器先生成 json 数据。 然后以 javascript 语法的方式,生成一个function , function 名字就是传递上来的参数 jsonp. 最后将 json 数据直接以入参的方式,放置到 function 中,这样就生成了一段 js 语法的文档,返回给客户端。
 3.客户端浏览器,解析script标签,并执行返回的 javascript 文档,此时数据作为参数,传入到了客户端预先定义好的 callback 函数里.(动态执行回调函数)

 json和jsonp的区别,ajax和jsonp的区别

 json和jsonp虽然只有一个字母的区别,但是它们之间扯不上关系。

json是一种轻量级的数据交换格式。

jsonp是一种跨域数据交互协议。

json的优点:(1)基于纯文本传递极其简单,(2)轻量级数据格式适合互联网传递,(3)容易编写和解析。

ajax和jsonp的区别:

相同点:都是请求一个url

不同点:ajax的核心是通过xmlHttpRequest获取内容

    jsonp的核心则是动态添加