以前在開發實驗室的一個雲服務,主要後端是使用java基於jfinal框架。咱們在開發中遇到了一個小小的問題,因爲咱們開發一般是將先後端分離利用AJAX進行交互的。可是AJAX是不容許跨域的哦,那麼問題來了,咱們該如何進行跨域AJAX呢?javascript
1、什麼是AJAX?java
Asynchronous JavaScript and XML (Ajax ) 是驅動新一代 Web 站點(流行術語爲 Web 2.0 站點)的關鍵技術。Ajax 容許在不干擾 Web 應用程序的顯示和行爲的狀況下在後臺進行數據檢索。使用 XMLHttpRequest
函數獲取數據,它是一種 API,容許客戶端 JavaScript 經過 HTTP 鏈接到遠程服務器。Ajax 也是許多 mashup 的驅動力,它可未來自多個地方的內容集成爲單一 Web 應用程序。web
2、爲何會有這個問題?ajax
ajax自己其實是經過XMLHttpRequest對象來進行數據的交互,而瀏覽器出於安全考慮,不容許js代碼進行跨域操做,因此會警告。json
3、常看法決辦法後端
(1)使用script標籤。跨域
script調用沒有域的限制,咱們能夠將輸出的數據假裝成script的變量。瀏覽器
(2)服務端腳本中轉安全
服務端腳本使用XMLHTTP沒有域的限制,可是耗費服務器的資源。服務器
(3)利用iframe
在同一個域名的各個子域名下,若是設置了document.domain,那麼是能夠相互調用JS的。
(4)JSONP
這個方法也是最解決正常AJAX和多人使用的。
JSONP(JSON with Padding)是一個非官方的協議,它容許在服務器端集成Script tags返回至客戶端,經過javascript callback的形式實現跨域訪問(這僅僅是JSONP簡單的實現形式)。
首先在客戶端註冊一個callback, 而後把callback的名字傳給服務器。
此時,服務器先生成 json 數據。
而後以 javascript 語法的方式,生成一個function , function 名字就是傳遞上來的參數 jsonp.
最後將 json 數據直接以入參的方式,放置到 function 中,這樣就生成了一段 js 語法的文檔,返回給客戶端。
客戶端瀏覽器,解析script標籤,並執行返回的 javascript 文檔,此時數據做爲參數,傳入到了客戶端預先定義好的 callback 函數裏.(動態執行回調函數)。
(5)CORS
這也是咱們此次採用的解決辦法。
CORS-CrossOrigin Resources Sharing,也即跨源資源共享,它定義了一種瀏覽器和服務器交互的方式來肯定是否容許跨域請求。它是一個妥協,有更大的靈活性,但比起簡單地容許全部這些的要求來講更加安全。簡言之,CORS就是爲了讓AJAX能夠實現可控的跨域訪問而生的。
可是CORS也具備必定的風險性,好比請求中只能說明來自於一個特定的域但不能驗證是否可信,並且也容易被第三方入侵。
4、在jfinal中使用CORS
在jfinal中使用cors很是簡單,這是得益於有cors的支持庫。咱們也將這個支持庫上傳到了咱們的CDN服務器上。
下載地址:http://cdn.besdlab.cn/cors-lib.rar
(1)在開發項目中加入支持庫
(2)修改web.xml,增長如下代碼
<filter> <filter-name>CORS</filter-name> <filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class> <init-param> <param-name>cors.allowOrigin</param-name> <param-value>*</param-value> </init-param> <init-param> <param-name>cors.supportedMethods</param-name> <param-value>GET, POST, HEAD, PUT, DELETE</param-value> </init-param> <init-param> <param-name>cors.supportedHeaders</param-name> <param-value>Accept, Origin, X-Requested-With, Content-Type, Last-Modified</param-value> </init-param> <init-param> <param-name>cors.exposedHeaders</param-name> <param-value>Set-Cookie</param-value> </init-param> <init-param> <param-name>cors.supportsCredentials</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>CORS</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
注意cors的攔截須要在jfinal以前!
(3)使用例子,咱們這裏用的是jQuery,其它框架相似。
$("#login").click(function() { $.ajax("http://測試地址", { type: "POST", xhrFields: { withCredentials: true, useDefaultXhrHeader: false }, data: { username: "測試", password: "測試" }, crossDomain: true, success: function(data, status, xhr) { } }); });
5、總結
cors這種解決方案不知道是爲何在國內不多能看到,甚至於百度搜索時都搜不到。咱們實驗室也在嘗試着使用這項技術解決跨域問題,若是你們有什麼更好的辦法或者是遇到了問題咱們能夠一塊兒探討和解決哦!