JSONP用法詳解
在介紹JSONP之前,先來介紹下面一個事實:
使用ajax來請求資料這個大家都不會陌生,如果暫時不瞭解可以參閱ajax教程板塊。
但是並不允許ajax進行跨域請求,也就是說在請求不同域伺服器的資源時候,會出現報錯現象。
這種現象是由瀏覽器的同源策略導致的,跨域請求會因為安全問題而被拒絕。
JSONP英文全程是JSON with Padding,正是為解決這種跨域請求問題而誕生,並不是一種正式傳輸協議。
名稱看起來和JSON關係密切,其實並非如此,只是返回請求資料通常是JSON結構,當然也可以是其他資料。
下面就分佈介紹一下JSONP的實現原理。
一.普通的ajax請求:
[HTML] 純文字檢視 複製程式碼執行程式碼<!DOCTYPE html> <html> <head> <meta charset=" utf-8"> <meta name="author" content="http://www.softwhy.com/" /> <title>螞蟻部落</title> <script src="http://libs.baidu.com/jquery/1.9.0/jquery.js"></script> <script> $.ajax({ type:'get', url:'http://www.softwhy.com/demo/JSON/php/antzone.php' }); </script> </head> <body> <div id="thediv"></div> </body> </html>
特別說明:千萬不要在本站執行此程式碼,因為這相當於同域請求,所以不會出現任何問題。
如果在其他域執行此程式碼的時候就會出現跨域問題,截圖如下:
二.html的自帶標籤可以實現跨域:
但是html的很多標籤自己就具有跨域功能,比如<script>標籤。
通常我們為了節省流量和提高速度,使用其他著名的CDN資源,比如上面程式碼中使用的jquery資源:
<script src="http://libs.baidu.com/jquery/1.9.0/jquery.js"></script>
很明顯上面的程式碼能夠實現跨域請求,其實凡是帶有src屬性的html標籤都具有跨域請求的能力,這個特點就是實現JSONP的契機。
三.實現程式碼:
我們希望獲取跨域伺服器上獲取xml檔案上的如下資料,並且顯示在指定的div中,xml檔案內容如下:
[XML] 純文字檢視 複製程式碼<?xml version="1.0" encoding="utf-8" ?> <bookstore> <book> <range>前端專區</range> <author>螞蟻部落</author> <target>css教程</target> </book> <book> <range>前端專區</range> <author>螞蟻部落</author> <target>div教程</target> </book> <book> <range>資源專區</range> <author>softwhy.com</author> <target>特效下載</target> </book> <book> <range>前端專區</range> <author>softwhy.com</author> <target>教程下載</target> </book> </bookstore>
很明顯不能使用ajax跨域請求此xml檔案,然後進行處理。
那麼JSONP就要出場了,首先通過後臺語言將上面的XML檔案內容轉換為JSON格式,看如下程式碼:
[PHP] 純文字檢視 複製程式碼<?php $path=$_SERVER["DOCUMENT_ROOT"].'/demo/JSON/XML/XML.xml'; $json=json_encode(simplexml_load_file($path)); ?>
轉換結果如下:
上面的unicode字元是將中文進行了轉碼,可以防止出現亂碼的情況。
然後在客戶端我們需要動態的建立一個<script>標籤,然後再進行請求以便實現跨域效果:
[JavaScript] 純文字檢視 複製程式碼function getBooks(){ var script=document.createElement('script'); script.setAttribute('type','text/javascript'); script.setAttribute('src','http://www.softwhy.com/demo/JSON/PHP/antzone.php?callback=Books'); document.body.appendChild(script); }
上面的程式碼動態建立了一個script標籤,然後設定標籤的src屬性值,這個屬性值最關鍵的地方是傳送一個函式的名稱,這個名稱會在php後臺經過處理包裝後,作為一個函式呼叫的形式返回,函式的引數就是轉換後的json格式資料,後臺轉換程式碼:
[PHP] 純文字檢視 複製程式碼<?php $path=$_SERVER["DOCUMENT_ROOT"].'/demo/JSON/XML/XML.xml'; $json=json_encode(simplexml_load_file($path)); $callbackFn=$_GET['callback']; echo "$callbackFn($json);"; ?>
完整前臺程式碼例項:
[HTML] 純文字檢視 複製程式碼執行程式碼<!DOCTYPE html> <html> <head> <meta charset=" utf-8"> <meta name="author" content="http://www.softwhy.com/" /> <title>螞蟻部落</title> <script> function books(books){ var books=books.book; var booksContainer=document.getElementById('books'); var str=""; for(var index=0;index<books.length;index++){ str=str+"<div>"+ books[index]["range"]+","+ books[index]["author"]+","+ books[index]["target"]+ "</div>"; } booksContainer.innerHTML=str } function getBooks(){ var script=document.createElement('script'); script.setAttribute('type','text/javascript'); script.setAttribute('src','http://www.softwhy.com/demo/JSON/php/antzone.php?callback=books'); document.body.appendChild(script); } window.onload=function(){ getBooks(); } </script> </head> <body> <div id="books"></div> </body> </html>
上面的程式碼實現了跨域請求效果,當然如果在本站執行不是跨域,在不同域下請求沒有任何問題。
下面做一下簡單總結:
(1).JSONP並不是一個官方的標準協議,而是程式設計師自己達成的一種約定俗成。
(2).實現跨域就是利用<script>標籤自帶的跨域能力。
(3).在請求頁面建立一個用來處理資料的函式。
(4).處理資料的函式名稱會被髮送到伺服器,經過包裝以後,要被處理的資料被當作函式的引數返回。
(5).後臺包裝返回的字串通過src加入scrpt標籤後就是一個js函式呼叫程式碼,於是跨域請求成功。
相關文章
- JSONP 用法JSON
- StringTie用法詳解
- extern用法詳解
- iconfont用法詳解
- Metasploit用法詳解
- ajax與jsonp的區別及用法JSON
- axios的用法詳解iOS
- Flutter ListView 用法詳解FlutterView
- Elasticsearch SQL用法詳解ElasticsearchSQL
- git stash用法詳解Git
- SVG <markers>用法詳解SVG
- Promise用法詳解(一)Promise
- Python self用法詳解Python
- Generator用法詳解+co
- MyBatis Generator 用法詳解MyBatis
- 詳解JSON和JSONP劫持檢測程式碼以及解決方法JSON
- react-dnd 用法詳解React
- struct的匿名用法詳解Struct
- golang package time 用法詳解GolangPackage
- Flutter之BoxDecoration用法詳解Flutter
- Flutter之Container用法詳解FlutterAI
- dataTransfer.setData() 用法詳解
- re.search()用法詳解
- Ubuntu mount命令用法詳解Ubuntu
- fcntl函式用法詳解函式
- cdMysql?using?用法示例詳解MySql
- c++ vector用法詳解C++
- Selenium用法詳解 -- selenium八大定位詳解
- Object.defineProperty的用法詳解Object
- Git tag標籤用法詳解Git
- 網路命令ifconfig用法詳解。
- java中printf中用法詳解Java
- AngularJS select中ngOptions用法詳解AngularJSGo
- Flutter之Row/Column用法詳解Flutter
- 使用python來操作redis用法詳解PythonRedis
- C# 之 static的用法詳解C#
- c++ 智慧指標用法詳解C++指標
- ADB 操作命令詳解及用法大全