Jsonp跨域,Ajax淺述
阿新 • • 發佈:2018-12-22
最近在進行歷史專案重構,前後端分離時候需要把介面封成jsonp,來解決域中的跨域問題。這裡簡單總結一波:
開發中由於同源策略,在一個Service上的應用是訪問不到另一個地址空間的資源的,所以在分散式應用中,需要進行跨域的操作,當然方法有很多,在前後分離中我們主要用的是jsonp解決這個問題。
下面說一下jsonp的簡單原理:
jsonp是通過<script>
標籤進行實現的,<script>
標籤具有無域的限制,正式這個類似漏洞的屬性,讓資源跨域訪問多了一種實現策略。
在進行通訊時,站內會建立一個<script>
元素,並且它的src屬性指向域外地址空間的資源,同時會定義一個callback回撥函式(函式名可自定義),類似callback({“name”:”hax”,”gender”:”Male”}) ;服務方會返回包裝後的json資料(jsonp-json padding),即JavaScript型別的資料。之後瀏覽器會呼叫回撥函式,進行解析”jsonp”資料;
下面上我的程式碼(前-中-後)中的中層,前端程式碼上面栗子都有,就只貼中層吧:
//進行物件jsonp化
jsonp(response, callback, basicPromotionResult);
//對回撥函式進行約束
protected void jsonp(HttpServletResponse response, String callback, Object result) {
if (callback.length() > 30) {
callback = callback.substring(0, 30 );
}
callback = callback.replaceAll("[^\\w\\_\\.]", " ");
outString(response, callback + "(" + GsonUtils.toJson(result) + ")");
}
//對相應頭進行封裝
public static void outString(HttpServletResponse response, String str) {
try {
response.setContentType("application/json;charset=utf-8" );
response.setCharacterEncoding("utf-8");
response.setHeader("Cache-Control", "no-cache");// 清除快取
response.setHeader("Pragma", "No-cache");
response.setDateHeader("Expires", -1);
response.setHeader("Cache-Control", "no-cache,no-store");
PrintWriter out = response.getWriter();
out.write(str);
out.close();
} catch (IOException e) {
log.error("LoginBaseAction.outString:" + e.getMessage(),e);
}
}
往往jsonp被Jquery封裝為Ajax,但其實ajax與jsonp的區別不在於是否跨域;
ajax通過服務端代理一樣可以實現跨域,jsonp本身也不排斥同域的資料的獲取。
其本質也是有區別的;
ajax的核心是通過XmlHttpRequest獲取非本頁內容,而jsonp的核心則是動態新增<script>
標籤來呼叫伺服器提供的js指令碼。
還有就是,jsonp是一種方式或者說非強制性協議,如同ajax一樣,它也不一定非要用json格式來傳遞資料,如果你願意,字串都行,只不過這樣不利於用jsonp提供公開服務。