這段時間面試 常常會問到這個問題。也就是說,若是你的前端想要獲取其餘域名下的數據,前端須要如何請求,後端須要如何設置。javascript
最多見的處理方式有兩種html
方法一,在java代碼中設置response.setHeader("Access-Control-Allow-Origin","*");便可解決ajax跨域的問題,其中星號表明容許所有請求前端
$.ajax({ type: "post", url: "http://192.168.1.88/testAjaxJson", contentType: "application/json", dataType: "json", success: function(){ alert("request succeed"); } });
@Controller public class TestController { /** * 使用普通json方式跨域請求 * @param response */ @RequestMapping(value="/testAjaxJson") public void testAjaxJson(HttpServletResponse response){ try { // 這裏設置爲任意域請求都能獲取到數據 response.setHeader("Access-Control-Allow-Origin","*"); // 這裏還能夠設置接收方式,固定域 兩者選其一 response.setHeader("Access-Control-Allow-Headers", "accept, content-type"); response.setHeader("Access-Control-Allow-Method", "POST"); response.setHeader("Access-Control-Allow-Origin", "http://192.168.1.88");
response.getWriter().print("{\"id\":1}"); response.flushBuffer(); } catch (Exception e) { e.printStackTrace(); } } }
在正式post以前,瀏覽器會先發出一個options請求(也叫preflight),同時header帶上origin還有Access-Control-Request-*:**之類的頭,服務器響應會返回相應的access-control-allow-origin,若是匹配,那麼瀏覽器就會發送正式post,不然就會出現上述錯誤。這也解答了,跨域訪問時,咱們明明發送的post請求,失敗的話,查看chrome network會發現是options方法的緣由。java
這裏的content-type不屬於(application/x-www-form-urlencoded,multipart/form-data,text/plain)中的任何一種,因此是複雜請求。jquery
複雜請求 第一次是options請求,http options請求跟get、post、head等同樣,都屬於http的請求方法,options方法,用來獲取服務器端某url支持的方法,response header中allow標誌支持的方法 面試
第二次纔是真正的請求ajax
方法二,使用jsonp的方式請求數據,後端需返回js方法調用,返回的數據放在參數中chrome
function testJsonp(){ $.ajax({ url:"http://192.168.1.88/testAjaxJsonp", type:"GET",//必須是get請求 dataType:"jsonp",//請求的數據類型 jsonp:"callback",//請求類型是回調 jsonpCallback:"callbackFunction",//數據請求成功時回調的方法 data:{ },//請求的數據 success:function(data){//執行完成返回的數據 alert(data.id);//輸出值是1 } }); }
@Controller public class TestController { @RequestMapping(value="/testAjaxJsonp") public void testAjaxJsonp(@RequestParam String callback,HttpServletResponse response){ try {
// 這裏jsonp返回的數據是固定格式 文後有詳細解釋 response.getWriter().print(callback+"({\"id\":1})"); response.flushBuffer(); } catch (Exception e) { e.printStackTrace(); } } }
jsonp的最基本的原理是:動態添加一個<script>標籤,而script標籤的src屬性是沒有跨域的限制的。這樣說來,這種跨域方式其實與ajax XmlHttpRequest協議無關了.json
JSONP是一個非官方的協議,它容許在服務器端集成Script tags返回至客戶端,經過javascript callback的形式實現跨域訪問JSONP即JSON with Padding。因爲同源策略的限制,XmlHttpRequest只容許請求當前源(域名、協議、端口)的資源。若是要進行跨域請求,咱們能夠經過使用html的script標記來進行跨域請求,並在響應中返回要執行的script代碼,其中能夠直接使用JSON傳遞javascript對象。這種跨域的通信方式稱爲JSONP。後端
jsonCallback 函數jsonp123(....): 是瀏覽器客戶端註冊的,獲取跨域服務器上的json數據後,回調的函數
Jsonp原理:
首先在客戶端註冊一個callback (如:'jsoncallback'), 而後把callback的名字(如:jsonp123)傳給服務器。注意:服務端獲得callback的數值後,要用jsonp123(......)把將要輸出的json內容包括起來,此時,服務器生成 json 數據才能被客戶端正確接收。
而後以 javascript 語法的方式,生成一個function , function 名字就是傳遞上來的參數 'jsoncallback'的值 jsonp123
最後將 json 數據直接以入參的方式,放置到 function 中,這樣就生成了一段 js 語法的文檔,返回給客戶端。
客戶端瀏覽器,解析script標籤,並執行返回的 javascript 文檔,此時javascript文檔數據,做爲參數,
傳入到了客戶端預先定義好的 callback 函數(如上例中jquery $.ajax()方法封裝的的success: function (json))裏.(動態執行回調函數)
能夠說jsonp的方式原理上和<script src="http://跨域/...xx.js"></script>是一致的(qq空間就是大量採用這種方式來實現跨域數據交換的) .JSONP是一種腳本注入(Script Injection)行爲,因此也有必定的安全隱患.
注意,jquey是不支持post方式跨域的.
但願總結能夠幫助到你們