JSONP(JSON with Padding)是數據格式JSON的一種「使用模式」,可讓網頁從別的網域要數據。另外一個解決這個問題的新方法是跨來源資源共享。javascript
因爲同源策略,通常來講位於server1.example.com的網頁沒法與不是 server1.example.com的服務器溝通,而HTML的 < script >元素是一個例外。利用 < script >元素的這個開放策略,網頁能夠獲得從其餘來源動態產生的JSON數據,而這種使用模式就是所謂的 JSONP。用JSONP抓到的數據並非JSON,而是任意的JavaScript,用 JavaScript解釋器運行而不是用JSON解析器解析。html
爲了理解這種模式的原理,先想像有一個回傳JSON文件的URL,而JavaScript 程序能夠用XMLHttpRequest跟這個URL要數據。假設咱們的URL是http://tools.42du.cn/jsonp/student/3 。假設iFat3的st_no是3,當瀏覽器經過URL傳遞iFat3的st_id,也就是抓取http://tools.42du.cn/jsonp/student/3,獲得:java
{"st_no":3,"st_name":"iFat3","st_desc":"iFat3是學校的超級學渣"}
這個JSON數據多是依據傳過去URL的查詢參數動態產生的。jquery
這個時候,把 < script >元素的src屬性設成一個回傳JSON的URL是能夠想像的,這也表明從HTML頁面經過script元素抓取 JSON是可能的。ajax
然而,一份JSON文件並非一個JavaScript程序。爲了讓瀏覽器能夠在 < script >元素運行,從src裏URL 回傳的必須是可運行的JavaScript。在JSONP的使用模式裏,該URL回傳的是由函數調用包起來的動態生成JSON,這就是JSONP的「填充(padding)」或是「前輟(prefix)」的由來。spring
慣例上瀏覽器提供回調函數的名稱看成送至服務器的請求中命名查詢參數的一部分,例如:json
<script type="text/javascript" src="http://tools.42du.cn/jsonp/student/3?callback=callback> </script>
服務器會在傳給瀏覽器前將JSON數據填充到回調函數(callback)中。瀏覽器獲得的迴應已不是單純的數據敘述而是一個腳本。在本例中,瀏覽器獲得的是:api
/**/callback({"st_no":3,"st_name":"iFat3","st_desc":"iFat3是學校的超級學渣"});
本例中的Jsonp利用的是Spring Framework的JSonp處理部分生成,詳細內容請閱讀官方文檔。連接見相關資料中的spring部分,本人強烈建意您在實際開發過程當中,先閱讀官方文檔,再進行代碼編寫。瀏覽器
Student模型對象的get和set方法未列出。服務器
public class Student extends BaseBean implements Serializable { private Integer st_no; private String st_name; private String st_desc; }
@ControllerAdvice @RequestMapping("/jsonp") public class StudentJsonpAdvice extends AbstractJsonpResponseBodyAdvice { private List<Student> students = new ArrayList<Student>(); public StudentJsonpAdvice() { super("callback"); initData(); } @RequestMapping(value="/student/all",method= RequestMethod.GET) @ResponseBody public List<Student> list(){ return students; } @RequestMapping(value="/student/{st_no}",method= RequestMethod.GET) @ResponseBody public Student info(@PathVariable Integer st_no){ if(st_no != null) { if(st_no > 0 && st_no <4) { return students.get(st_no -1); } return students.get(0); } return null; } private void initData() { Student st1 = new Student(1,"王美麗","王美麗是學校的校花"); Student st2 = new Student(2,"毛三胖","毛三胖是學校的學霸"); Student st3= new Student(3,"iFat3","iFat3是學校的超級學渣"); students.add(st1); students.add(st2); students.add(st3); } }
利用JQuery的ajax方法取得全部學生的數據,並利用回調函數(callback)將數據插入到頁面中。更多JQuery的ajax方法參見相關資料中的JQuery部分。
function callback(data) { $(data).each(function(i,item){ $("#stu_ul").append("<li>"+item.st_name+"</li>"); }); } $(document).ready(function () { $.ajax({ type:"get", dataType:"jsonp", url:"http://tools.42du.cn/jsonp/student/all", jsonpCallback:"callback" }); })