1. 程式人生 > 程式設計 >通過例項解析json與jsonp原理及使用方法

通過例項解析json與jsonp原理及使用方法

1.json與jsonp的引入

在ajax中 JSON用來解決資料交換問題,而JSONP來實現跨域。

備註:跨域也可以通過伺服器端代理來解決;

理解:JSON是一種資料交換格式,而JSONP是一種依靠開發人員的聰明才智創造出的一種非官方跨域資料互動協議。

2.JSON:是一種基於文字的資料交換方式,或者叫做資料描述格式,是否該選用它首先肯定要關注它所擁有的優點。

JSON的優點:

  • 1) 基於純文字,跨平臺傳遞極其簡單;
  • 2) Javascript原生支援,後臺語言幾乎全部支援;
  • 3) 輕量級資料格式,佔用字元數量極少,特別適合網際網路傳遞;
  • 4) 可讀性較強,雖然比不上XML那麼一目瞭然,但在合理的依次縮排之後還是很容易識別的;
  • 5) 容易編寫和解析,當然前提是你要知道資料結構;

JSON的格式或者叫規則:

JSON能夠以非常簡單的方式來描述資料結構,XML能做的它都能做,因此在跨平臺方面兩者完全不分伯仲。

  • 1) JSON只有兩種資料型別描述符,大括號{}和方括號[],其餘英文冒號:是對映符,英文逗號,是分隔符,英文雙引號""是定義符。
  • 2) 大括號{}用來描述一組“不同型別的無序鍵值對集合”(每個鍵值對可以理解為OOP的屬性描述),方括號[]用來描述一組“相同型別的有序資料集合”(可對應OOP的陣列)。
  • 3) 上述兩種集合中若有多個子項,則通過英文逗號,進行分隔。
  • 4) 鍵值對以英文冒號:進行分隔,並且建議鍵名都加上英文雙引號"",以便於不同語言的解析。
  • 5) JSON內部常用資料型別無非就是字串、數字、布林、日期、null 這麼幾個,字串必須用雙引號引起來,其餘的都不用,日期型別比較特殊,這裡就不展開講述了,

只是建議如果客戶端沒有按日期排序功能需求的話,那麼把日期時間直接作為字串傳遞就好,可以省去很多麻煩。

示列1:{} 用來描述一組“不同型別的無序鍵值對集合”
    var person = {
      "Name": "Bob","Age": 32,"Company": "IBM","Engineer": true
    }
  示列2:[] 用來描述一組“相同型別的有序資料集合”
    var members = [
      {
        "Name": "Bob","Engineer": true
      },{
        "Name": "John","Age": 20,"Company": "Oracle","Engineer": false
      },{
        "Name": "Henry","Age": 45,"Company": "Microsoft","Engineer": false
      }
    ]
    //讀取其中John的公司名稱
    var johnsCompany = members[1].Company;
  
  示列3:{}中包含的[]使用
    var conference = {
      "Conference": "Future Marketing","Date": "2012-6-1","Address": "Beijing","Members":
      [
        {
          "Name": "Bob","Engineer": true
        },{
          "Name": "John","Engineer": false
        },{
          "Name": "Henry","Engineer": false
        }
      ]
    }
  
    // 讀取參會者Henry是否工程師
    var henryIsAnEngineer = conference.Members[2].Engineer;

3.什麼是JSONP

JSONP(JSON with Padding)是資料格式 JSON 的一種“使用模式”,可以讓網頁從別的網域要資料。由於同源策略,一般來說位於 server1.example.com 的網頁無法與不是 server1.example.com的伺服器溝通,而 HTML 的 <script> 元素是一個例外。利用<script> 元素的這個開放策略,網頁可以得到從其他來源動態產生的 JSON 資料,而這種使用模式就是所謂的 JSONP。用 JSONP 抓到的資料並不是 JSON,而是任意的 JavaScript,用 JavaScript 直譯器執行而不是用 JSON 解析器解析。

3.1 JSOPN跨域的原理:script標籤的src屬性,支援跨域;它的基本思想是,網頁通過新增一個<script>元素,向伺服器請求JSON資料,這種做法不受同源政策限制;伺服器收到請求後,將資料放在一個指定名字的回撥函式裡傳回來。

3.2 JSOP包含兩部分:回撥函式和資料,回撥函式是在響應到來時應該呼叫的函式,一般通過查詢字串新增; 資料就是傳入回撥函式中的JSON資料,確切的說,是一個JSON物件,可以直接訪問。

3.3 JSONP的缺點:

1) 只能實現GET,沒有POST;

2) 從其他域中載入的程式碼可能不安全;難以確定JSONP請求是否失敗(XHR有error事件),常見做法是使用定時器指定響應的允許時間,超出時間認為響應失敗。

為了方便客戶端使用資料逐漸形成非正式傳輸協議jsonp該協議的一個要點就是允許使用者傳遞一個callback引數給服務端,然後服務端返回資料時會將這個callback引數作為函式名來包裹住json資料 這樣客戶端就可以隨意定製自己的函式來自動處理返回資料

示列:

function ajaxFun(){
      var strUrl="http://www.b.com/demo/json.txt";
       $.ajax({
        type:"get",url:strUrl,dataType: 'jsonp',jsonp: "callback",//傳遞給請求處理程式或頁面的,用以獲得jsonp回撥函式名的引數名(一般預設為:callback)
        jsonpCallback: "flightHandler",//自定義的jsonp回撥函式名稱,預設為jQuery自動生成的隨機函式名,也可以寫"?",jQuery會自動為你處理資料
        success: function(data){
          alert('您查到的資訊:票價' + data.price + '元,餘-票' + data.tickets + '張。');
        },error: function(XMLHttpRequest,textStatus,errorThrown){
          alert("error");
          // 狀態碼
          console.log(XMLHttpRequest.status);
          // 狀態
          console.log(XMLHttpRequest.readyState);
          // 錯誤資訊  
          console.log(textStatus);
         }
      });
    }

備註:

其中 sucess中的程式碼片段也可以不寫,可以單獨建立一個回撥函式來呼叫返回的資料。如下一樣可以獲得資料。

var flightHandler = function (data) {
alert('您查到的資訊:票價' + data.price + '元,餘票' + data.tickets + '張。');
};

需要注意的是,ajax跨域請求(jsonp)中,服務端返回資料格式必須是:flightHandler({ "price":"120","tickets":"20"});如果直接這樣的json格式{ "price":"120","tickets":"20"},將會報parser error的錯誤.請注意這個函式最後的分號";",必須加上,否則,如果同一個頁面有多個ajax請求,並且在資料沒有返回時,再發出其它ajax請求時,有可能出現parsererror出錯提示.這種錯誤很隱敝,在開發時,不容易發現,在併發測試時,就很容易暴露出.

服務端程式碼示列:

public String jsonReturn(HttpServletResponse response,String callback,Map<String,Object> jsonMap) {
    if (org.apache.commons.lang.StringUtils.isEmpty(callback)) {
      return appAjaxJson(response,getJson(jsonMap));
    }
    return appAjaxJson(response,callback + "(" + getJson(jsonMap) + ")");
  }

  public String appAjaxJson(HttpServletResponse response,String jsonString) {
    return appAjax(response,jsonString,"text/html");
  }

  public String appAjax(HttpServletResponse response,String content,String type) {
    try {
      response.setContentType(type + ";charset=UTF-8");
      response.setHeader("Access-Control-Allow-Origin","*");//表示支援跨域請求
      // 如果IE瀏覽器則設定頭資訊如下
      if ("IE".equals(type)) {
        response.addHeader("XDomainRequestAllowed","1");
      }
      response.setHeader("Pragma","No-cache");
      response.setHeader("Cache-Control","no-cache");
      response.setDateHeader("Expires",0);
      response.getWriter().write(content);
      response.getWriter().flush();
    } catch (IOException e) {
      this.logException(e);
    }
    return null;
  }

4、JSON.stringify()、JSON.parse()、toString()

4.1 JSON.stringify():將入參(JavaScript值)轉換為 JSON 字串;

示列1:
  let arr = [1,2,3];
  JSON.stringify(arr);//"[1,3]"
  typeof JSON.stringify(arr);//"string"

  示例2:
  //判斷陣列是否包含某物件
  let data = [
    {name:'echo'},{name:'聽風是風'},{name:'天子笑'},],val = {name:'天子笑'};
  JSON.stringify(data).indexOf(JSON.stringify(val)) !== -1;//true

  //判斷兩陣列/物件是否相等
  let a = [1,3],b = [1,3];
  JSON.stringify(a) === JSON.stringify(b);//true

4.2 JSON.parse():將JSON字串轉為一個物件;

示列:

let string = '[1,3]';
console.log(JSON.parse(string))//[1,3]
console.log(typeof JSON.parse(string))//object

4.3 JSON.stringify()與 toString()的區別

let arr = [1,3];
JSON.stringify(arr);//'[1,3]'
arr.toString();//1,3

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。