ajax跨域問題

ajax自己其實是經過XMLHttpRequest對象來進行數據的交互,而瀏覽器出於安全考慮,不容許js代碼進行跨域操做,會警告,因此纔出現ajax跨域的問題。javascript

配置Web服務器支持跨域訪問html

這裏描述以Tomcat爲Web服務器狀況下的解決辦法,在Java Web程序的WEB-INF下的web.xml文件中加入以下配置便可。java

1
2
3
4
5
6
7
8
9
<!--cors filter-->
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

注意:org.apache.catalina.filters.CorsFilter下面有好幾個配置的選項,上面沒有配置時就採用系統的默認配置。在實際生產環境要根據須要進行配置來提升安全性。好比cors.allowed.origins配置容許訪問的源地址,默認爲全部,即*。此外,還有cors.allowed.methods,cors.allowed.headers等等。jquery

經過jQuery的ajax進行跨域,這實際上是採用的jsonp的方式來實現的。web

jsonp是英文json with padding的縮寫。它容許在服務器端生成script tags至返回至客戶端,也就是動態生成javascript標籤,經過javascript callback的形式實現數據讀取。ajax

html頁面端示例代碼:apache


//首先要引入jquery的js包
jQuery(document).ready(function(){
$.ajax({ json

      type : "get", //jquey是不支持post方式跨域的 api

      async:false, 跨域

      url : "http://api.taobao.com/apitools/ajax_props.do", //跨域請求的URL

      dataType : "jsonp",

      //傳遞給請求處理程序,用以得到jsonp回調函數名的參數名(默認爲:callback)

      jsonp: "jsoncallback",

     //自定義的jsonp回調函數名稱,默認爲jQuery自動生成的隨機函數名

     jsonpCallback:"success_jsonpCallback",

     //成功獲取跨域服務器上的json數據後,會動態執行這個callback函數

     success : function(json){

           alert(json);
     }
   });
});

 

服務器端示例代碼,以java爲例:

   


public void jsonpTest() throws IOException{

HttpServletRequest request = ServletActionContext.getRequest();

HttpServletResponse response = ServletActionContext.getResponse();

//根據html指定的jsonp回調函數的參數名,獲取回調函數的名稱

//callbackName的值其實就是:success_jsonpCallback

String callbackName = (String)request.getAttribute("jsoncallback");

//簡單模擬一個json字符串,實際可以使用google的gson進行轉換,次數經過字符串拼接

//{"name":"張三","age":28}

//\是對"號進行轉義

String jsonStr = "{\"name\":\"張三\",\"age\":28}";

//最終返回的數據爲:success_jsonpCallback({"name":"張三","age":28})

String renderStr = callbackName+"("+jsonStr+")";

response.setContentType("text/plain;charset=UTF-8");

response.getWriter().write(renderStr);
}

jsonp的原理:

 

首先在客戶端註冊一個callback (如:'jsoncallback'), 而後把callback的名字(如:success_jsonpCallback)傳給服務器端對應的處理函數。

服務器先生成須要返回給客戶端的 json 數據。而後以 javascript 語法的方式,生成一個function , function 名字就是傳遞上來的參數(jsoncallback)的值(success_jsonpCallback) 。

最後將 json 數據直接以入參的方式,放置到 function 中,這樣就生成了一段 js 語法的文檔,返回給客戶端。
客戶端瀏覽器,解析script標籤,並將服務器端返回的數據,做爲參數,
傳入到了客戶端預先定義好的 callback 函數(如上例中jquery $.ajax()方法封裝的的success: function (json))裏。

實際上跨域是經過動態增長script來加載數據,沒法直接得到數據,因此須要使用回調函數。

 


$.ajax({
url: url,
data: data,
success: callback,
dataType: json
});

 

getJson跨域獲取數據
$.getJSON("http://api.taobao.com/apitools/ajax_props.do&jsoncallback=?",
function (data) {
alert(data);
}
);

 

執行原理:

 

發送請求時須要傳一個callback的回調函數名到服務器端,服務器端拿到這個回調函數名,再將返回數據用參數的形式反回到客戶端,這樣客戶端就可以調到。

因此發送請求URL的地址後面必定要上jsoncallback=?這樣的參數,jquery會將?號自動替換成自動生成的回調函數的名稱。

因此最終的實際請求爲:http://api.taobao.com/apitools/ajax_props.do&jsoncallback=jsonp1322444422697

因此和ajax的方式想比較,也就是callback函數一個是自動生成的函數名,一個是手工指定的函數名。

相關文章
相關標籤/搜索