簡單的來講,出於安全方面的考慮,頁面中的JavaScript沒法訪問其餘服務器上的數據,即「同源策略」。而跨域就是經過某些手段來繞過同源策略限制,實現不一樣服務器之間通訊的效果。ajax
具體策略限制狀況可看下錶:json
URL | 說明 | 容許通訊 |
http://www.a.com/a.js http://www.a.com/b.js |
同一域名下 | 容許 |
http://www.a.com/lab/a.js http://www.a.com/script/b.js |
同一域名下不一樣文件夾 | 容許 |
http://www.a.com:8000/a.js http://www.a.com/b.js |
同一域名,不一樣端口 | 不容許 |
http://www.a.com/a.js https://www.a.com/b.js |
同一域名,不一樣協議 | 不容許 |
http://www.a.com/a.js http://127.0.0.100/b.js |
域名和域名對應ip | 不容許 |
http://www.a.com/a.js http://script.a.com/b.js |
主域相同,子域不一樣 | 不容許 |
http://www.a.com/a.js http://a.com/b.js |
同一域名,不一樣二級域名(同上) | 不容許 |
http://www.a.com/a.js http://www.b.com/b.js |
不一樣域名 | 不容許 |
JSON(JavaScript Object Notation) 是一種輕量級的數據交換格式,而JSONP(JSON with Padding)則是JSON 的一種「使用模式」,經過這種模式能夠實現數據的跨域獲取。 跨域
在同源策略下,在某個服務器下的頁面是沒法獲取到該服務器之外的數據的,但img、iframe、script等標籤是個例外,這些標籤能夠經過src屬性請求到其餘服務器上的數據。利用script標籤的開放策略,咱們能夠實現跨域請求數據,固然,也須要服務端的配合。當咱們正常地請求一個JSON數據的時候,服務端返回的是一串JSON類型的數據,而咱們使用JSONP模式來請求數據的時候,服務端返回的是一段可執行的JavaScript代碼。安全
舉個例子,假如須要從服務器(http://www.a.com/user?id=123)獲取的數據以下:服務器
那麼,使用JSONP方式請求(http://www.a.com/user?id=123?callback=foo)的數據將會是以下: app
固然,若是服務端考慮得更加充分,返回的數據可能以下: 函數
這時候咱們只要定義一個foo()函數,並動態地建立一個script標籤,使其的src屬性爲http://www.a.com/user?id=123?callback=foo: jsonp
即可以使用foo函數來調用返回的數據了。 url
第一種方法是在ajax函數中設置dataType爲'jsonp': spa
第二種方法是利用getJSON來實現,只要在地址中加上callback=?參數便可:
也能夠簡單地使用getScript方法:
JSONP在開放API中能夠起到很是重要的做用,開放API是運用在開發者本身的應用上,而許多應用每每是在開發者的服務器上而不是在新浪微博的服務器上,所以跨域請求數據成爲開發者們所須要解決的一大問題,廣大開放平臺應該實現對JSONP的支持,這一點新浪微博開放平臺便作的很是好(雖然某些API裏沒有說明,但其實是能夠使用JSONP方式調用的)。
一、頁面請求
function complete(){
var data = {
"enterprise_id":"8316",
"receiver_name":"王敏",
"province_code":"110000",
"city_code":"110100",
"district_code":"110102",
"province_name":"北京市",
"city_name":"市轄區",
"district_name":"西城區",
"address":"這裏是詳細地址",
"contact_phone":"18721703659",
"default_address":"0"
};
$.ajax({
url:"http://usermanage.yaoex.com:8080/enterpriseInfo/saveReceiverAddress",
data:data,
dataType :'JSONP',
jsonp: "callbackSaveAddress",
jsonpCallback:"success_jsonp",
contentType: "application/json;charset=utf-8",
success: function (data) {
console.info(data);
}
});
}
二、服務器響應
/*** 新增收發貨地址信息* @return* @throws Exception* {"enterprise_id":"8316","receiver_name":"小小蔡芽", "province_code":"110000","city_code":"110100","district_code":"110102","province_name":"北京市","city_name":"市轄區","district_name":"西城區","address":"這裏是詳細地址","contact_phone":"18721703659","default_address":"0"}*/@RequestMapping(value = "/saveReceiverAddress")@ResponseBodypublic String saveReceiverAddress(HttpServletRequest request,@RequestBody UsermanageReceiverAddress usermanageReceiverAddress) {String jsonpCallback = request.getParameter("callbackSaveAddress");Map<String, Object> resp = new HashMap<String, Object>();try {//獲取用戶信息User user = UsermanageUserUtil.getCurrentUser(request);if (null == user) {resp.put("result", "error");resp.put("msg", " 未能正常獲取登陸用戶信息!");logger.info(" 未能正常獲取登陸用戶信息!");return jsonpCallback + "(" + JSONObject.toJSONString(resp) + ")";}usermanageReceiverAddress.setEnterprise_id(String.valueOf(user.getEnterprise_id()));List<UsermanageReceiverAddress> usermanageReceiverAddressList= userManageEnterpriseService.queryReceiverAddress(String.valueOf(user.getEnterprise_id()));if(null != usermanageReceiverAddressList && usermanageReceiverAddressList.size()>=10){resp.put("result", "error");resp.put("msg","添加失敗,您只能保存10條收發貨地址信息!");logger.info("添加失敗,您只能保存10條收發貨地址信息!");return jsonpCallback + "(" + JSONObject.toJSONString(resp) + ")";}//新增地址插入正式表userManageEnterpriseService.saveAddress(usermanageReceiverAddress);resp.put("result", "success");resp.put("msg", "地址保存成功!");return jsonpCallback + "(" + JSONObject.toJSONString(resp) + ")";} catch (Exception e) {logger.error(e.getMessage());resp.put("result", "error");resp.put("msg", "地址保存失敗!");return jsonpCallback + "(" + JSONObject.toJSONString(resp) + ")";}}