標籤:錯誤 family 函數 運行 add 整合 port enter ajax跨域請求
項目開發中,某個可獨立、也可整合的子業務模組須要向外開放相關API介面,先說下項目本身使用了jersery來實現RESTful webservice以名詞形式公布API。有意思的是在實際的操作中同事卻通過Ajax跨域請求的方式去調用該API,先不說成功與否,這樣的方式本就是“滑稽"的。和他一起探討了此種做法的不合理性,之後選擇jersey client的方式進行遠程調用。只是他在跨域請求中遇到了問題,自己閑暇時間予以解決,這才是此篇文章的由來。
jQuery對跨域請求有兩種解決方式各自是jQuery的jquery.ajax jsonp格式和jquery.getScript方式,並且這兩種方式都僅僅支援get方法。
這裡主要談的是jsonp跨域的實現。
json格式我們倒是經常使用,可是jsonp就不那麼經常使用了,所以首先須要對jsonp要有一個瞭解。
JSONP解釋
在解釋JSONP之前,我們須要瞭解下”同源策略“這個概念,這對理解跨域有協助。基於安全的原因,瀏覽器是存在同源策略機制的,同源策略阻止從一個源載入的文檔或指令碼擷取或設定還有一個源載入額文檔的屬性。有點繞,說的簡單點就是瀏覽器限制指令碼僅僅能和同協議、同網域名稱、同port的指令碼進行互動。
JSONP就是為瞭解決這一問題的,JSONP是英文JSON with Padding的縮寫,是一個非官方的協議。他同意服務端產生script tags傳回值client,通過javascript callback的形式來實現網站訪問。JSONP是一種script tag的注入,將server返回的response加入到頁面是實現特定功能。
簡而言之,JSONP本身不是複雜的東西,就是通過scirpt標籤對javascript文檔的動態解析繞過了瀏覽器的同源策略。
JSONP原理及實現
接下來,來實際類比一個跨域請求的解決方式。後端為Spring MVC架構的,前端則通過Ajax進行跨域訪問。
1、首先client須要注冊一個callback(服務端通過該callback(jsonp)能夠得到js函數名(jsonpCallback))。然後以JavaScript語
法的方式,產生一個function
2、接下來,將JSON資料直接以入參的方式,放置到function中,這樣就產生了一段js文法文檔,返回給client。
3、最後client瀏覽器動態解析script標籤,並運行返回的JavaScript文法文檔片段,此時資料作為參數傳入到了預先定義好的
回呼函數裡(動態運行回呼函數)。
這樣的動態解析js文檔和eval函數是類似的。
接下來就是怎樣實現了,client代碼。
$.ajax({ type: "get", async: false, url: "http://localhost:8080/buy/get", dataType: "jsonp", jsonp: "callbackparam", //服務端用於接收callback調用的function名的參數 jsonpCallback: "success_jsonpCallback", //callback的function名稱,服務端會把名稱和data一起傳遞迴來 success: function(json) { alert(json[0].name); } });
註解:jsonp會建立一個查詢字串參數callback=?
,這個參數會載入請求的URL後面,服務端應當在JSON資料前加上回呼函數
名,以便完畢一個JSONP請求。也就是說server端須要對返回的資料做處理,格式為例如以下形式:
jsonpCallback([{ name:"jhon"}])
接下來看server端針對上述代碼的處理:
@RequestMapping("/get")public void get(HttpServletRequest req,HttpServletResponse res) {res.setContentType("text/plain");String callbackFunName =req.getParameter("callbackparam");//得到js函數名稱try {res.getWriter().write(callbackFunName + "([ { name:\"John\"}])"); //返回jsonp資料} catch (IOException e) {e.printStackTrace();}}
前端Ajax跨域請求觸發之後,可以有效得到JSON資料,情況例如以下:
至此,Ajax跨域請求也已經攻克了,只是還是有兩點地方須要注意:
1、沒有關於JSONP調用的錯誤處理,動態插入的指令碼有效,則運行調用,無效就默默失敗(無不論什麼提示)。
2、JSONP被不信任的服務使用會有一定的安全隱患,不信任的服務提供的指令碼可能是惡意的。
jQuery中Ajax+Spring MVC實現跨域請求