ajax跨域問題處理

來源:互聯網
上載者:User

這段時間面試 經常會問到這個問題。也就是說,如果你的前端想要擷取其他網域名稱下的資料,前端需要如何請求,後端需要如何設定。

最常見的處理方式有兩種

方法一,在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方法的原因。

這裡的content-type不屬於(application/x-www-form-urlencoded,multipart/form-data,text/plain)中的任何一種,所以是複雜請求。

       複雜請求   第一次是options請求,http options請求跟get、post、head等一樣,都屬於http的要求方法,options方法,用來擷取伺服器端某url支援的方法,response header中allow標誌支援的方法 

      第二次才是真正的請求

方法二,使用jsonp的方式請求資料,後端需返回js方法調用,返回的資料放在參數中

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跨域的原理解析

  jsonp的最基本的原理是:動態添加一個<script>標籤,而script標籤的src屬性是沒有跨域的限制的。這樣說來,這種跨域方式其實與ajax XmlHttpRequest協議無關了.

  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方式跨域的.

 

希望總結可以協助到大家

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.