首頁 > web前端 > js教程 > 主體

ajax前後台跨域請求處理方法

小云云
發布: 2018-02-09 09:46:13
原創
1552 人瀏覽過

最近一直在搞公眾號前台開發,遇到了ajax跨域請求的問題,像地區的省-市-縣三級聯動、汽車品牌-車系-車款的三級聯動查詢等都需要調用外部介面(其他工程項目的介面)完成。本文主要介紹透過前台跨域請求處理以及後台跨域的資料處理方式,詳細分析了ajax跨域的問題。

跨域請求需要藉助後台代碼接收callback回呼函數,對json資料進行進一步處理;前台再用ajax請求向伺服器發送callback參數,並指定資料格式為jsonp。

一、後台對跨域請求進行處理

1.CarBrandController.java(汽車品牌介面java檔),這裡列出的方法主要用來根據不同的level值查詢對應的品牌、車系、車款,在這裡對跨域請求做一個接收回調函數的處理,如果返回的callback為null,則不是跨域請求,不需要做特殊處理,直接打印json接口數據即可;如果傳回的callback不為null,表示跨域請求,這時要對json資料做一個特殊處理,即在json資料的外層加一對小括號包起來,具體請看HttpAdapter.java檔中的printlnJSONObject方法。


public void json(HttpServletRequest request,HttpServletResponse response){ 
  Map<String,Object>map=new HashMap<String, Object>(); 
  String id = request.getParameter("id");      //接收ajax请求带过来的id 
  String level = request.getParameter("level");   //接收ajax请求带过来的level 
  String callback=request.getParameter("callback"); //接收ajax请求带过来的callback参数 
  if ("1".equals(level)) {             //如果level是&#39;1&#39;,则查询第一级目录内容 
    map.put("results", this.carBrandService.findByAttr(null, "first_letter asc")); //调用查询方法,结果放入map 
  } else if ("2".equals(level)) {          //如果level是&#39;2&#39;,则查询第二级目录内容 
    map.put("results", this.carSerieService.findByAttr("parent_id="+id, "first_letter asc"));//调用查询方法,结果放入map 
  } else if ("3".equals(level)) {          //如果level是&#39;3&#39;,则查询第三极目录内容 
    map.put("results", this.carModelYearService.findByAttr("parent_id="+id, "jian_pin desc"));//调用查询方法,结果放入map 
  } 
  map.put("level",level); 
  if (null==callback) {               //如果接收的callback值为null,则是不跨域的请求,输出json对象 
    HttpAdapter.printlnObject(response, map); 
  }else{                      //如果接收的callback值不为null,则是跨域请求,输出跨域的json对象 
  HttpAdapter.printlnJSONPObject(response, map, callback); 
  } 
}
登入後複製

2.HttpAdapter.java(輸出物件的java檔案),printlnObject方法列印正常json字串;printlnJSONObject方法對json字串進行了特殊處理。


/** 
 * 打印对象 
 * @param response 
 * @param object 
*/ 
public static void printlnObject(HttpServletResponse response,Object object){ 
  PrintWriter writer=getWriter(response); 
  writer.println(JSON.toJSONString(object)); 
} 
/** 
 * 打印跨域对象 
 * @param response 
 * @param object 
*/ 
public static void printlnJSONPObject(HttpServletResponse response,Object object,String callback){ 
  PrintWriter writer=getWriter(response); 
  writer.println(callback+"("+JSON.toJSONString(object)+")"); 
}
登入後複製

二、前台ajax跨域請求資料

寫法1:向伺服器發送一個參數callback=? ,同時指定dataType為'jsonp'的格式,跨域請求時指定的資料格式必須是jsonp的形式。


function loadData(obj,level,id,value){ 
  $.ajax({  
    url:&#39;http://192.168.1.106:8086/carBrand/json.html?level=&#39;+level+&#39;&id=&#39;+id+&#39;&callback=?&#39;,   //将callback写在请求url后面作为参数携带 
    type:&#39;GET&#39;, 
    async:false, 
    dataType:&#39;jsonp&#39;, 
    success:function(data){         
      console.log(data);             
      //其他处理(动态添加数据元素)       
  });    
}
登入後複製

寫入法2:callback不需要寫在url中,但要指定jsonp參數為'callback',並給jsonpCallback參數一個值。


function loadData(obj,level,id,value){ 
  $.ajax({  
    url:&#39;http://192.168.1.106:8086/carBrand/json.html?level=&#39;+level+&#39;&id=&#39;+id, 
    type:&#39;GET&#39;, 
    dataType:&#39;jsonp&#39;, 
    jsonp: &#39;callback&#39;,          //将callback写在jsonp里作为参数连同请求一起发送 
    jsonpCallback:&#39;jsonpCallback1&#39;,    
    success:function(data){            
    console.log(data);       
}); }
登入後複製

以上兩種寫法的意思是一樣的,只是寫法不同罷了。

接下來補充jsonp的工作原理。

三、jsonp跨域的原理解析

jsonp的最基本的原理是:動態加入一個<script>標籤,而script標籤的src屬性是沒有跨域的限制的。這樣說來,這種跨域方式其實與ajax XmlHttpRequest協議無關了.<br></p> <p>JSONP是一個非官方的協議,它允許在伺服器端集成Script tags返回到客戶端,透過javascript callback的形式實作跨域存取JSONP即JSON with Padding。由於同源策略的限制,XmlHttpRequest只允許請求目前來源(網域名稱、協定、連接埠)的資源。如果要進行跨域請求,我們可以透過使用html的script標記來進行跨域請求,並在回應中傳回要執行的script程式碼,其中可以直接使用JSON傳遞javascript物件。這種跨域的通訊方式稱為JSONP。 </p> <p>jsonCallback 函數jsonp1236827957501(....): 是瀏覽器用戶端註冊的,取得跨網域伺服器上的json資料後,回呼的函數</p> <p><strong>Jsonp原理:</strong></p> <p>先在客戶端註冊一個callback (如:'jsoncallback'), 然後把callback的名字(如:jsonp1236827957501)傳給伺服器。注意:服務端得到callback的數值後,要用jsonp1236827957501(......)把將要輸出的json內容包括起來,此時,伺服器產生 json 資料才能被客戶端正確接收。 </p> <p>接著以javascript 語法的方式,產生一個function , function 名字就是傳遞上來的參數'jsoncallback'的值jsonp1236827957501 .</p> <p>#最後將json 資料直接以入參的方式,放置到function 中,這樣就產生了一段js 語法的文檔,回傳給客戶端。 </p> <p>客戶端瀏覽器,解析script標籤,並執行返回的javascript 文檔,此時javascript文檔資料,作為參數,<br>傳入到了客戶端預先定義好的callback 函數(如上例中jquery $.ajax()方法封裝的的success: function (json))裡.(動態執行回呼函數)</p> <p>可以說jsonp的方式原理上和<script src="http://跨域/...xx.js"></script>是一致的(qq空間就是大量採用這種方式來實現跨域資料交換的) .JSONP是一種腳本注入(Script Injection)行為,所以也有一定的安全隱患.

注意,jquey是不支援post方式跨域的.

#相關推薦:

vue使用axios跨域請求資料實例詳解

原生JS實作ajax與ajax的跨域請求

#實例詳解Ajax跨域請求的原理


以上是ajax前後台跨域請求處理方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板