最近在開發過程中,使用ajax去非同步調取圖片。在開發中這個功能沒什麼問題,可以後來提測,重新部署之後就有問題了,這就是ajax的跨域問題。
ajax本身是不支援跨域的,這是由於javascript的同源策略所導致。但是我們可以通過其他方法來解決ajax的跨域問題。
1 由於我們是利用了jquery來寫的ajax,我們一開始是準備 利用jsonp來解決的,用戶端類似下面寫法
代碼如下 |
複製代碼 |
$.ajax({ type : "get", async:false, url : "http://www.xxx.com/ajax.do", dataType : "jsonp", jsonp: "callbackparam",//服務端用於接收callback調用的function名的參數 jsonpCallback:"success_jsonpCallback",//callback的function名稱 success : function(json){ alert(json); alert(json[0].name); }, error:function(){ alert('fail'); } }); 伺服器端寫法 public void ProcessRequest (HttpContext context) { context.Response.ContentType = "text/plain"; String callbackFunName = context.Request["callbackparam"]; context.Response.Write(callbackFunName + "([ { name:"John"}])"); } |
這個方法其實蠻簡單的,跟我們之前寫的改動不大。
2 由於我們這次項目開發的頁面比較多,改動起來涉及的地方就比較多了。最後是採取的 直接修改nginx配置實現的。平時對反向 Proxy的理解也就是 緩衝、安全、負載平衡,所以查了下方向代理
反向 Proxy(Reverse Proxy),顧名思義,就是代理的反向功能。我們使用代理,可以訪問一些我們所不能直接存取到的網路,或者可以隱藏自己的真實身份。而反向 Proxy,可以在不暴露內部伺服器的情況下,讓外部使用者訪問我們內部、防火牆後的服務。
使用反向 Proxy主要有以下好處:
1 請求的統一控制,包括設定許可權、過濾規則等;
2 隱藏內部服務真真實位址,暴露在外的只是反向 Proxy伺服器位址;
3 實現負載平衡,內部可以採用多台伺服器來組成伺服器叢集,外部還是可以採用一個地址訪問;
4 解決Ajax跨域問題。
5 作為真實伺服器的緩衝,解決瞬間負載量大的問題。
項目完成之後,對ajax跨域問題在網上查了查,還知道了通過HTML中可以請求跨域資源的標籤引用來達到跨域的目的,其實jsonp本質上就是採用了這種辦法。
HTML中可以請求跨域資源的標籤是很多的,
Script無疑是最合適的。在請求每一個指令碼資源時,瀏覽器都會去解析並運行指令檔內定義的函數,或需要馬上執行的JavaScript代碼,我們可以通過伺服器返回一段指令碼或JSON對象,在瀏覽器解析執行,從而達到跨域請求的目的。使用script標籤來實現跨域請求,只能使用get方法請求伺服器資源。並且傳參的長度也受到地址欄長度的限制。
補充:有了jQuery之後,如何來解決ajax的跨域問題:
代碼如下 |
複製代碼 |
<html> <head> <title>JQuery學習</title> <script src="jquery-1.4.2.min.js" type="text/javascript"></script> <script type="text/javascript"> $(document).ready(function(){ var oBtnTest = $("#btnTest"); oBtnTest.click(function(){ oBtnTest.disabled = true; var oResult = $("#result"); oResult.html("loading").css("color","red"); jQuery.getScript("http://www.111cn.net /test/js.txt", function(){ oResult.html("name:" + Dylan.name + "<br/>email:" + Dylan.email).css("color","black"); oBtnTest.disabled = false; }); }); }); </script> </head> <body> <button id="btnTest">BtnTest</button> <div id="result"></div> </body> </html> |
遠程伺服器端js.txt中的內容為:
var Dylan= {name:"Dylan",email:Dylan@163.com}
筆者感覺這種方式更加簡潔。呵呵。當然,讀者可以根據實際情況,任意選擇實現方式。
怎麼樣,其實很簡單吧,我看到過很多人不願意去正視ajax所存在的技術瓶頸,其實AJAX更應該是Ajax而不是AJAX,突出第一個A是想強調其實AJAX發揚的是一種非同步傳輸的方法,而不是具體到底使用了哪種技術。
其實,在json資料格式之後,有一種更牛X的“jsonp”,也可以實現ajax的跨域通訊。其實jsonp不是一種資料格式,只是對我介紹的第二種方式做了改進。從jQuery1.2 版本開始,jQuery 擁有對 JSONP 回調的本地支援。