• <fieldset id="8imwq"><menu id="8imwq"></menu></fieldset>
  • <bdo id="8imwq"><input id="8imwq"></input></bdo>
    最新文章專題視頻專題問答1問答10問答100問答1000問答2000關(guān)鍵字專題1關(guān)鍵字專題50關(guān)鍵字專題500關(guān)鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專題關(guān)鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
    問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
    當前位置: 首頁 - 科技 - 知識百科 - 正文

    Ajax與JSON的一些學習總結(jié)

    來源:懂視網(wǎng) 責編:小采 時間:2020-11-27 22:52:23
    文檔

    Ajax與JSON的一些學習總結(jié)

    Ajax與JSON的一些學習總結(jié):1.1.1 摘要 Ajax技術(shù)的核心是XMLHttpRequest對象(簡稱XHR),可以通過使用XHR對象獲取到服務器的數(shù)據(jù),然后再通過DOM將數(shù)據(jù)插入到頁面中呈現(xiàn)。雖然名字中包含XML,但Ajax通訊與數(shù)據(jù)格式無關(guān),所以我們的數(shù)據(jù)格式可以是XML或JSON等格式。 XMLHt
    推薦度:
    導讀Ajax與JSON的一些學習總結(jié):1.1.1 摘要 Ajax技術(shù)的核心是XMLHttpRequest對象(簡稱XHR),可以通過使用XHR對象獲取到服務器的數(shù)據(jù),然后再通過DOM將數(shù)據(jù)插入到頁面中呈現(xiàn)。雖然名字中包含XML,但Ajax通訊與數(shù)據(jù)格式無關(guān),所以我們的數(shù)據(jù)格式可以是XML或JSON等格式。 XMLHt

    1.1.1 摘要
    Ajax技術(shù)的核心是XMLHttpRequest對象(簡稱XHR),可以通過使用XHR對象獲取到服務器的數(shù)據(jù),然后再通過DOM將數(shù)據(jù)插入到頁面中呈現(xiàn)。雖然名字中包含XML,但Ajax通訊與數(shù)據(jù)格式無關(guān),所以我們的數(shù)據(jù)格式可以是XML或JSON等格式。

    XMLHttpRequest對象用于在后臺與服務器交換數(shù)據(jù),具體作用如下:

    在不重新加載頁面的情況下更新網(wǎng)頁
    在頁面已加載后從服務器請求數(shù)據(jù)
    在頁面已加載后從服務器接收數(shù)據(jù)
    在后臺向服務器發(fā)送數(shù)據(jù)

    1.1.2 正文
    XMLHttpRequest是一個JavaScript對象,它是由微軟設計,并且被Mozilla、Apple和Google采納,W3C正在標準化它。它提供了一種簡單的方法來檢索URL中的數(shù)據(jù)。

    我們要創(chuàng)建一個XMLHttpRequest實例,只需new一個就OK了:
    代碼如下:


    //// Creates a XMLHttpRequest object.
    var req = new XMLHttpRequest();

    也許有人會說:“這可不行??!IE6不支持原始的XHR對象”,確實是這樣,我們在后面將會介紹支持IE6或更老版本創(chuàng)建XHR對象的方法。

    XMLHttpRequest的用法
    在創(chuàng)建XHR對象后,接著我們要調(diào)用一個初始化方法open(),它接受五個參數(shù)具體定義如下:
    代碼如下:


    void open(
    DOMString method, //"GET", "POST", "PUT", "DELETE"
    DOMString url,
    optional boolean async,
    optional DOMString user,
    optional DOMString password
    );

    通過上面的定義我們知道open()方法的簽名包含五個參數(shù),其中有參數(shù)method和url地址是必填的,假設我們針對URL: myxhrtest.aspx發(fā)送GET請求獲取數(shù)據(jù),具體定義如下:
    代碼如下:

    var req = new XMLHttpRequest();
    req.open(
    "GET",
    "myxhrtest.aspx",
    false
    );

    通過上述代碼會啟動一個針對myxhrtest.aspx的GET請求,這里有兩點要注意:一是URL相對于執(zhí)行代碼的當前頁面(使用絕對路徑);二是調(diào)用open()方法并不會真正發(fā)送請求,而只是啟動一個請求準備發(fā)送。

    只能向同一個域中使用相同端口和協(xié)議的URL中發(fā)送請求;如果URL與啟動請求的頁面有任何差別,都會引發(fā)安全錯誤。

    要真正發(fā)送請求要使用send()方法,send()方法接受一個參數(shù),即要作為請求主體發(fā)送的數(shù)據(jù),如果不需要通過請求主體發(fā)送數(shù)據(jù),我們必須傳遞一個null值。在調(diào)用send()之后,請求就會被分派到服務器,完整Ajax請求代碼如下:
    代碼如下:


    var req = new XMLHttpRequest();
    req.open(
    "GET",
    "myxhrtest.aspx",
    false
    );
    req.send(null);

    在發(fā)送請求之后,我們需要檢查請求是否執(zhí)行成功,首先可以通過status屬性判斷,一般來說,可以將HTTP狀態(tài)代碼為200作為成功標志。這時,響應主體內(nèi)容會保存到responseText中。此外,狀態(tài)代碼為304表示請求的資源并沒有被修改,可以直接使用瀏覽器緩存的數(shù)據(jù),Ajax的同步請求代碼如下:
    代碼如下:

    if (req != null) {
    req.onreadystatechange = function() {
    if ((req.status >= 200 && req.status < 300) || req.status == 304) {
    //// Do something.
    }
    else {
    alert("Request was unsuccessful: " + req.status);
    }
    };
    req.open("GET", "www.myxhrtest.aspx", true);
    req.send(null);
    }

    前面我們定義了Ajax的同步請求,如果我們發(fā)送異步請求,那么在請求過程中javascript代碼會繼續(xù)執(zhí)行,這時可以通過readyState屬性判斷請求的狀態(tài),當readyState = 4時,表示收到全部響應數(shù)據(jù),屬性值的定義如下:

    readyState值

    描述

    0

    未初始化;尚未調(diào)用open()方法

    1

    啟動;尚未調(diào)用send()方法

    2

    已發(fā)送;但尚未收到響應

    3

    接收;已經(jīng)收到部分響應數(shù)據(jù)

    4

    完成;收到全部響應數(shù)據(jù)

    表1 readyState屬性值

    同步請求:發(fā)生請求后,要等待服務器執(zhí)行完畢才繼續(xù)執(zhí)行當前代碼。

    異步請求:發(fā)生請求后,無需等到服務器執(zhí)行完畢,可以繼續(xù)執(zhí)行當前代碼。

    現(xiàn)在我們要增加判斷readyState屬性值,當readyState = 4時,表示全部數(shù)據(jù)接收完成, 所以Ajax的異步請求代碼如下:
    代碼如下:


    if (req != null) {
    req.onreadystatechange = function() {

    //// Checks the asyn request completed or not.
    if (req.readyState == 4) {
    if ((req.status >= 200 && req.status < 300) || req.status == 304) {
    //// Do something.
    }
    else {
    alert("Request was unsuccessful: " + req.status);
    }
    }
    };
    req.open("GET", "www.myxhrtest.aspx", true);
    req.send(null);
    }

    Ajax同源請求
    現(xiàn)在我們對Ajax的請求實現(xiàn)有了初步的了解,接下來我們將通過具體的例子說明Ajax請求的應用場合和局限。

    在日常網(wǎng)絡生活中,我們在瀏覽器的地址中輸入要訪問的URL并且回車,瀏覽器會向服務器發(fā)送請求,當服務器收到請求后,把相應的請求頁面發(fā)送回瀏覽器,我們會發(fā)現(xiàn)頁面大部分加載完畢,有些還沒有加載完畢??偟脕碚f,采用異步加載方式不會影響已加載完畢的頁面瀏覽,我們可以通過Ajax實現(xiàn)異步加載。

    這里我們以AdventureWorks數(shù)據(jù)庫為例,把產(chǎn)品表(Product)中的數(shù)據(jù)通過報表呈現(xiàn)給用戶,我們可以通過多種方法實現(xiàn)該報表需求,這里我們將通過Ajax實現(xiàn)該功能。

    首先,我們要把后臺數(shù)據(jù)轉(zhuǎn)換為JSON格式,接下來我們定義Product表的數(shù)據(jù)庫訪問對象(DAO),具體的實現(xiàn)代碼如下:
    代碼如下:


    /// <summary>
    /// The product datatable dao.
    /// </summary>
    public class ProductDao
    {
    /// <summary>
    /// Initializes a new instance of the <see cref="ProductDao"/> class.
    /// </summary>
    public ProductDao()
    {
    }

    /// <summary>
    /// Gets or sets the product id.
    /// </summary>
    public int Id { get; set; }

    /// <summary>
    /// Gets or sets the product name.
    /// </summary>
    public string Name { get; set; }

    /// <summary>
    /// Gets or sets the product serial number.
    /// </summary>
    public string SerialNumber { get; set; }

    /// <summary>
    /// Gets or sets the product qty.
    /// </summary>
    public short Qty { get; set; }
    }

    前面我們定義了Product表的數(shù)據(jù)庫訪問對象——ProductDao,它包含四個屬性分別是產(chǎn)品的Id,名稱,序列號和銷售數(shù)量。

    接下來,讓我們實現(xiàn)Product表的數(shù)據(jù)庫操作類。
    代碼如下:


    /// <summary>
    /// Product table data access manager.
    /// </summary>
    public class ProductManager
    {
    /// <summary>
    /// The query sql.
    /// </summary>
    private const string Query =
    "SELECT ProductID, Name, ProductNumber, SafetyStockLevel FROM Production.Product";

    /// <summary>
    /// Stores the object of <see cref="ProductDao"/> into list.
    /// </summary>
    private IList<ProductDao> _products = new List<ProductDao>();

    /// <summary>
    /// Gets all products in product table.
    /// </summary>
    /// <returns>
    /// The list of <see cref="ProductDao"/> object.
    /// </returns>
    public IList<ProductDao> GetAllProducts()
    {
    using (var con = new SqlConnection(ConfigurationManager.ConnectionStrings["SQLCONN"].ToString()))
    using (var com = new SqlCommand(Query, con))
    {
    con.Open();
    using (var reader = com.ExecuteReader(CommandBehavior.CloseConnection))
    {
    while (reader.Read())
    {
    var product = new ProductDao
    {
    Id = (int)reader["ProductID"],
    Name = (string)reader["Name"],
    SerialNumber = (string)reader["ProductNumber"],
    Qty = (short)reader["SafetyStockLevel"]
    };
    _products.Add(product);
    }
    }
    }

    return _products;
    }
    }

    前面我們實現(xiàn)了Product表的數(shù)據(jù)庫操作類——ProductManager,它包含兩個私有字段Quey和_products,還有一個獲取Product表中數(shù)據(jù)的方法——GetAllProducts()。

    通過實現(xiàn)ProductDao和ProductManager,而且我們提供GetAllProducts()方法,獲取Product表中的數(shù)據(jù),接下來我們要調(diào)用該方法獲取數(shù)據(jù)。

    為了使數(shù)據(jù)通過JSON格式傳遞給頁面,這里我們要創(chuàng)建一般處理程序(ASHX文件),

    一般處理程序適用場合:

    創(chuàng)建動態(tài)圖片
    返回REST風格的XML或JSON數(shù)據(jù)
    自定義HTML

    ajax1

    圖1一般處理程序

    把一般處理程序文件添加到項目中時,會添加一個擴展名為.ashx的文件,現(xiàn)在我們創(chuàng)建一個一般處理程序ProductInfo,具體代碼如下:

    代碼如下:


    <%@ WebHandler Language="C#" Class="ProductInfo" %>
    using System.Runtime.Serialization.Json;
    using System.Web;
    using ASP.App_Code;
    /// <summary>
    /// The product data handler.
    /// </summary>
    public class ProductInfo : IHttpHandler {
    public void ProcessRequest (HttpContext context) {
    context.Response.ContentType = "application/json";
    // Creates a <see cref="ProductManager"/> oject.
    var manager = new ProductManager();
    // Invokes the GetAllProducts method.
    var products = manager.GetAllProducts();
    // Serializes data to json format.
    var json = new DataContractJsonSerializer(products.GetType());
    json.WriteObject(context.Response.OutputStream, products);
    }
    // Whether can resuable by other handler or not.
    public bool IsReusable {
    get {
    return false;
    }
    }
    }

    大家注意到ProductInfo類實現(xiàn)了IHttpHandler接口,該接口包含一個方法ProcessRequest()方法和一個屬性IsReusable。ProcessRequest()方法用于處理入站的Http請求。在默認情況下,ProductInfo類會把內(nèi)容類型改為application/json,然后我們把數(shù)據(jù)通過JSON格式寫入輸入流中;IsReusable屬性表示相同的處理程序是否可以用于多個請求,這里我們設置為false,如果為了提高性能也可以設置為true。
    如下圖所示,我們通過ProductInfo類成功地實現(xiàn)獲取數(shù)據(jù)到響應流中,并且以JSON格式顯示出來。

    ajax2

    圖2 Http請求
    當我們請求ProductInfo時, 首先它會調(diào)用ProcessRequest()方法,接著調(diào)用GetAllProducts()方法從數(shù)據(jù)庫中獲取數(shù)據(jù),然后把數(shù)據(jù)通過JSON格式寫入到響應流中。
    現(xiàn)在,我們已經(jīng)成功地把數(shù)據(jù)通過JSON格式寫入到響應流當中,接著我們將通過Ajax方式請求數(shù)據(jù)并且把數(shù)據(jù)顯示到頁面中。
    首先,我們定義方法createXHR()用來創(chuàng)建XMLHttpRequest對象,前面我們提到IE6或者更老的版本不支持XMLHttpRequest()方法來創(chuàng)建XMLHttpRequest對象,所以我們要在createXHR()方法中,增加判斷當前瀏覽器是否IE6或更老的版本,如果是,就要通過MSXML庫的一個ActiveX對象實現(xiàn)。因此,在IE中可能遇到三種不同版本的XHR對象(MSXML2.XMLHttp6.0,MSXML2.XMLHttp3.0和MSXML2.XMLHttp)。
    代碼如下:

    // Creates a XMLHttpRequest object bases on web broswer.
    function createXHR() {
    // Checks whether support XMLHttpRequest or not.
    if (typeof XMLHttpRequest != "undefined") {
    return new XMLHttpRequest();
    }
    // IE6 and elder version.
    else if (typeof ActiveXObject != "undefined") {
    if (typeof arguments.callee.activeXString != "string") {
    var versions = [
    "MSXML2.XMLHttp6.0",
    "MSXML2.XMLHttp3.0",
    "MSXML2.XMLHttp"];
    for (var i = 0; i < versions.length; i++) {
    try {
    var xhr = new ActiveXObject(versions[i]);
    arguments.callee.activeXString = versions[i];
    return xhr;
    }
    catch (ex) {
    throw new Error(ex.toString());
    }
    }
    return new ActiveXObject(arguments.callee.activeXString);
    }
    else {
    throw new Error("No XHR object available");
    }
    }
    return null;
    }
    $(document).ready(function() {
    GetDataFromServer();
    });

    前面我們定義了一個比較通用的方法用來創(chuàng)建XMLHttpRequest對象,并且它支持IE6或更老版本創(chuàng)建XMLHttpRequest對象,接下來我們將通過Ajax方法請求數(shù)據(jù)。
    代碼如下:

    function GetDataFromServer() {
    // Creates a XMLHttpRequest object.
    var req = new createXHR();
    if (req != null) {
    req.onreadystatechange = function() {
    if (req.readyState == 4) {
    if ((req.status >= 200 && req.status < 300) || req.status == 304) {
    ////alert(req.responseText);
    var jsonTextDiv = document.getElementById("jsonText");
    // Deserializes JavaScript Object Notation (JSON) text to produce a JavaScript value.
    var data = JSON.parse(req.responseText);
    for (var i = 0; i < data.length; i++) {
    var item = data[i];
    var div = document.createElement("div");
    div.setAttribute("class", "dataItem");
    // Inserts data into the html.
    div.innerHTML = item.Name + " sold " + item.Qty + "; Product number: " + item.SerialNumber;
    jsonTextDiv.appendChild(div);
    }
    }
    else {
    alert("Request was unsuccessful: " + req.status);
    }
    }
    };
    // Sends a asyn request.
    req.open("GET", "ProductInfo.ashx", true);
    req.send(null);
    }
    }

    由于前面我們介紹過Ajax發(fā)生請求的方法,所以不再重復介紹了,但我們注意到GetDataFromServer()方法中,獲取responseText數(shù)據(jù)(JSON格式),然后通過parse()方法把JSON格式數(shù)據(jù)轉(zhuǎn)換為Javascript對象,最后把數(shù)據(jù)插入到div中,頁面呈現(xiàn)效果如下:

    ajax3

    圖3 Ajax請求結(jié)果

    現(xiàn)在,我們成功地把數(shù)據(jù)

    輸出到頁面當中,也許用戶還會覺得用戶體驗不好,那么我們給就該頁面增加CSS樣式。

    由于時間的關(guān)系,我們已經(jīng)把CSS樣式定義好了,具體如下:
    代碼如下:


    #header {
    width: 100%;
    margin-left: 10px;
    margin-right: 10px;
    background-color:#480082;
    color: #FFFFFF;
    }
    body {
    margin-left: 40px;
    margin-right: 40px;
    }
    div#jsonText {
    background-color: #d9d9d9;
    -webkit-border-radius: 6px;
    border-radius: 6px;
    margin: 10px 0px 0px 0px;
    padding: 0px;
    border: 1px solid #d9d9d9;
    }
    div.dataItem {
    font-family: Verdana, Helvetica, sans-serif;
    color: #434343;
    padding: 10px;
    }
    div.dataItem:nth-child(2n) {
    background-color: #fafafa;
    }
    div.dataItem:first-child {
    -webkit-border-top-left-radius: 6px;
    -webkit-border-top-right-radius: 6px;
    border-top-left-radius: 6px;
    border-top-right-radius: 6px;
    }
    div.dataItem:last-child {
    -webkit-border-bottom-left-radius: 6px;
    -webkit-border-bottom-right-radius: 6px;
    border-bottom-left-radius: 6px;
    border-bottom-right-radius: 6px;
    }

    我們刷新一下頁面,OK現(xiàn)在頁面效果好多了。

    ajax4

    圖4 Ajax請求結(jié)果

    同源策略與跨源策略
    上面我們獲取頁面和數(shù)據(jù)都是在同源請求情況下,也就是說,客戶端瀏覽器請求的頁面和數(shù)據(jù)都是屬于同一域名、同一端口和同協(xié)議。

    同源策略:阻止從一個域上加載的腳本獲取或操作另一個域上的文檔屬性。也就是說,受到請求的URL的域必須與當前Web頁面的域相同、相同端口。這意味著瀏覽器隔離來自不同源的內(nèi)容,以防止它們之間的操作。

    ajax6

    圖5同源請求過程

    在一些情況下,我們不可以避免地要地需要從其他域名或服務器中跨域請求數(shù)據(jù),但前面提到Ajax只能向同一個域中使用相同端口和協(xié)議的URL中發(fā)送請求;如果URL與啟動請求的頁面有任何差別,都會引發(fā)安全錯誤。

    跨源策略(CORS):是一個Web瀏覽器技術(shù)規(guī)范,它定義了一個方法讓Web服務器允許其他域名頁面訪問它的資源??缭床呗远x了一個方法讓瀏覽器和服務器可以交互決定是否允許跨源請求。

    ajax5

    圖6跨源請求過程

    大家注意到同源請求中我們使用的是JSON格式,但在跨源請求中卻是使用JSONP,這時大家可能有點困惑,坦然我剛開始學習的時候也是這樣的。

    首先我們必須理解JSON和JSONP的區(qū)別:JSON是一種數(shù)據(jù)格式,而JSONP像是通過一個方法名來封裝JSON格式;由于瀏覽器允許跨源請求<script>資源,如我們的HTML頁面代碼中使用了Google的jQuery庫,當我們Web程序發(fā)送跨源請求后,服務器給我們提供響應數(shù)據(jù),但服務器無法預知接受JSON數(shù)據(jù)的方法名,所以我們要提供一個方法名。

    Ajax跨源請求
    跨域請求數(shù)據(jù)解決方案主要有如下解決方法:

    JSONP方式
    表單POST方式
    服務器代理
    Html5的XDomainRequest
    Flash request
    在介紹JSONP方式解決跨域請求數(shù)據(jù)之前,首先我們看看JSONP的定義。

    JSONP(JSON with Padding)是一個非官方的協(xié)議,它允許在服務器端集成Script tags返回至客戶端,通過Javascript callback的形式實現(xiàn)跨域訪問(這僅僅是JSONP簡單的實現(xiàn)形式)。

    由于同源策略的限制,XMLHttpRequest只允許請求當前源(域名、協(xié)議、端口)的資源,為了實現(xiàn)跨域請求,可以通過script標簽實現(xiàn)跨域請求,然后在服務端

    輸出JSON數(shù)據(jù)并執(zhí)行回調(diào)函數(shù),從而解決了跨域的數(shù)據(jù)請求。

    假設博客園提供一個API接口:http://www.cnblogs.com/hotblogs/json,供開發(fā)者調(diào)用獲取熱門博文。

    這里我們可以通過兩種方式調(diào)用該接口:

    1. 用Javascript定義回調(diào)函數(shù)
    其實,通過Javascript定義回調(diào)函數(shù)調(diào)用該接口比較直觀,我們只需告訴服務器接收數(shù)據(jù)的方法名就OK了,比如:

    http://www.cnblogs.com/hotblogs/json? callback=myFunction

    其中myFunction是我們在頁面自定義的函數(shù)用來接收服務器回傳的數(shù)據(jù),myFunction的定義如下:
    代碼如下:


    // The call back function.
    function myFunction(data) {
    // Your code here.
    }

    2. 使用jQuery的Ajax方法
    假設我們想在博客中增加顯示浪微博的公共微博信息,我們可以在博客中調(diào)用微博提供的API獲取跨源數(shù)據(jù),接下來,我們將使用jQuery的Ajax方法獲取跨域數(shù)據(jù)。

    首先,查看微博API文檔找到了公共微博的API接口statuses/public_timeline 獲取最新的公共微博消息,它支持JSON或XML格式數(shù)據(jù)。

    參數(shù)

    必選

    類型及范圍

    說明

    source

    true

    string

    申請應用時分配的AppKey,調(diào)用接口時候代表應用的唯一身份。(采用OAuth授權(quán)方式不需要此參數(shù))

    count

    false

    int,缺省值20,最大值200

    每次返回的記錄數(shù)

    count

    false

    int,缺省值20,最大值200

    每次返回的記錄數(shù)

    表2請求參數(shù)

    上面的請求參數(shù)只有source(AppKey)是必須的,所以我們需要向微博申請AppKey,在調(diào)用API時,只需把我們的AppKey傳遞給接口就OK了。

    接下來讓我們看一下微博數(shù)據(jù)組成,這里我們使用JSON viewer查看微博的數(shù)據(jù)組成,具體數(shù)據(jù)如下:

    ajax8

    圖7微博JSON數(shù)據(jù)

    通過上圖,我們知道微博的數(shù)據(jù)信息很豐富,它是由一些基礎(chǔ)數(shù)據(jù)類型和復雜數(shù)據(jù)類型user組成的,接下來我們將使用jQuery實現(xiàn)調(diào)用微博接口方法。
    首先,我們定義一個全局的對象,它包含三個屬性分別是:numWeibo、appendTo和appKey,還有三個方法loadWeibo()、timeAgo()和clean(),具體定義如下:
    代碼如下:


    JQWeibo = {
    // The number of weibos display in the page.
    // Sets the number of weibos, append class and app key.
    numWeibo: 15,
    appendTo: '#jsWeibo',
    // The appkey you apply from weibo.
    appKey: YourAppKey,
    // The function to get weibo data.
    loadWeibo: function() {
    },
    /**
    * Convert the time to relative time.
    * @return {string} relative time like "8 minutes ago"
    */
    timeAgo: function(dateString) {
    },
    ify: {
    clean: function(weibo) {
    return this.hash(this.at(this.list(this.link(weibo))));
    }
    } // ify
    };

    上面我們定義了一個對象JQWeibo,其中l(wèi)oadWeibo()方法使用jQuery的Ajax方法向微博API發(fā)送跨源請求,接下來讓我們實現(xiàn)該方法吧。
    代碼如下:

    // The function to get weibo data.
    loadWeibo: function() {
    $.ajax({
    // Weibo API.
    url: "http://api.t.sina.com.cn/statuses/public_timeline.json",
    type: "GET",
    dataType: "jsonp",
    data: {
    source: JQWeibo.appKey,
    count: JQWeibo.numWeibo
    },
    // When the requet completed, then invokes success function.
    success: function(data, textStatus, xhr) {
    // Sets html structure.
    var html =
    '<div class="weibo">' +
    '<a target="_blank">USER</a>' +
    ':WEIBO_TEXT<div class="time">AGO</div>';
    // Appends weibos into html page.
    for (var i = 0; i < data.length; i++) {
    $(JQWeibo.appendTo).append(
    html.replace('WEIBO_TEXT', JQWeibo.ify.clean(data[i].text))
    // Uses regex and declare DOMAIN as global, if found replace all.
    .replace(/DOMAIN/g, data[i].user.domain)
    .replace(/USER/g, data[i].user.screen_name)
    .replace('AGO', JQWeibo.timeAgo(data[i].created_at))
    );
    }
    }
    })
    }

    現(xiàn)在,我們使用$.ajax()方法向微博API發(fā)送跨源請求,而且我們向API傳遞了JQWeibo.appKey和JQWeibo.numWeibo,當請求完成后,調(diào)用Success()方法把JSON數(shù)據(jù)插入的頁面當中。
    頁面的HTML代碼如下:
    代碼如下:

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
    "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    <title>Weibo Feed</title>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
    <link rel="stylesheet" type="text/css" href="css/WeiboFeed.css">
    </head>
    <body>
    <div id="jsWeibo"></div>
    </body>
    </html>

    ajax9
    圖8 跨源數(shù)據(jù)
    如上圖所示,我們使用$.ajax()方法調(diào)用公共微博接口,當成功獲取服務器回調(diào)數(shù)據(jù)插入到我們的頁面當中。
    1.1.3 總結(jié)
    本文主要介紹了Ajax在同源請求適用性,但在跨源請求中其存在的局限性,進而介紹Ajax和JSONP在跨源請求下解決方法。
    回答qianlifeng關(guān)于跨源請求的幾個問題:
    1.一般的跨源不用jsonp請求為什么會報錯?和同源的不都是一個請求么?(可能對ajax了解不深)
    答:首先跨源請求的解決方法不僅僅有JSON,本文中提及了其他方法,如:表單POST方式、服務器代理、Html5的XDomainRequest和Flash request等;而你提到報錯,我覺得你首先要確認數(shù)據(jù)格式是否正確。關(guān)于跨原請求和同源請求本文已經(jīng)給出了介紹。
    2.關(guān)于“用Javascript定義回調(diào)函數(shù)”那塊看的不是很明白。傳遞當前頁面的一個js方法給跨源服務器,為什么就能跨源請求了呢?(JSONP?) 服務端根據(jù)這個js方法做了什么操作?。?
    答:首先我們理解JSON是一種數(shù)據(jù)格式,而JSONP像似通過一個方法名來封裝JSON格式;而跨源請求不是說指定一個回調(diào)函數(shù)實現(xiàn)的,而是我們利用了瀏覽器允許跨源請求<script>資源,你也可以我的HTML代碼中使用的是Google提供的jQuery庫,這也說明了<script>資源可以跨源請求。當我們發(fā)送跨源請求后,服務器會返回JSONP,但服務器無法預知接受JSON數(shù)據(jù)的方法名,所有我們要把函數(shù)名告訴(傳遞)服務器。
    代碼如下:

    //JSON
    {"name":"JK_Rush","id":23}
    //JSONP
    func({"name":"JK_Rush","id":23});

    3.看你新浪微博的那個例子,是jquery的ajax對跨源做了處理?能不能說說您提到的兩種跨源方式的區(qū)別或者不同的應用場景,還是隨便都一樣?
    答:是通過$.ajax()方法實現(xiàn)的,如果你想使用動態(tài)Javascript實現(xiàn)也可以;至于兩種跨源的區(qū)別已經(jīng)在博文中指出了。
    回答@On the road....關(guān)于JSON反序列化為對象的實現(xiàn):
    答:一般我們可以通過三種方法把JSON數(shù)據(jù)反序列化為對象,分別是:ASP.NET AJAX中引入的JavaScriptSerializer,WCF中引入的DataContractJsonSerializer,以及Json.NET。
    假設,我們獲取到員工信息(employee)的JSON數(shù)據(jù),它包含兩個屬性分別是id和復雜屬性name,具體如下所示:
    代碼如下:

    [
    {
    "id": "82105",
    "name": {
    "lastName": "Huang",
    "firstName": "JK"
    }
    },
    {
    "id": "82106",
    "name": {
    "lastName": "Leung",
    "firstName": "Cindy"
    }
    }
    ]
    string data = "[{\"id\":\"82105\",\"fullname\":{\"lastName\":\"Huang\",\"firstName\":\"JK\"}}," +
    "{\"id\":\"82106\",\"fullname\":{\"lastName\":\"Leung\",\"firstName\":\"Cindy\"}}]";

    根據(jù)上述JSON數(shù)據(jù)的組成,我們定義出相應的對象模型,具體定義如下:
    代碼如下:

    // The Employee model.
    public class Employee
    {
    public int Id { get; set; }
    public Name FullName { get; set; }
    }
    // The Name model.
    public class Name
    {
    public string FirstName { get; set; }
    public string LastName { get; set; }
    }

    接下來,我們將介紹使用JavaScriptSerializer,Json.NET和DataContractJsonSerializer反序列化JSON數(shù)據(jù)為對象。
    JavaScriptSerializer
    代碼如下:

    var serializer = new JavaScriptSerializer();
    var employees= serializer.Deserialize<Employee[]>(data);Json.NET
    using (var stringReader = new StringReader(data))
    using (var jsonTextReader = new JsonTextReader(stringReader))
    {
    var serializer = new JsonSerializer();
    var employees = serializer.Deserialize<Employee[]>(jsonTextReader);
    }

    DataContractJsonSerializer
    對于使用WCF的DataContractJsonSerializer方法,我們需要在對象模型添加DataContract和DataMember屬性,具體定義如下:
    代碼如下:

    [DataContract]
    public class Employee
    {
    [DataMember(Name = "id")]
    public int Id { get; set; }
    [DataMember(Name = "fullname")]
    public Name FullName { get; set; }
    }
    [DataContract]
    public class Name
    {
    [DataMember(Name = "firstName")]
    public string FirstName { get; set; }
    [DataMember(Name = "lastName")]
    public string LastName { get; set; }
    }

    接著我們使用ReadObjects()方法把JSON數(shù)據(jù)轉(zhuǎn)換為對象。
    代碼如下:

    using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(data)))
    {
    DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(List<Employee>));
    var employee = (List<Employee>)serializer.ReadObject(ms);
    }

    參考 

    https://developer.mozilla.org/en/XMLHttpRequest
    http://www.w3schools.com/xml/xml_http.asp
    http://msdn.microsoft.com/en-us/library/windows/apps/cc836466%28v=vs.85%29.aspx
    http://ntesmailfetc.blog.163.com/blog/static/206287061201241011546581/
    http://justcoding.iteye.com/blog/1366102
    http://www.queness.com/post/8567/create-a-dead-simple-twitter-feed-with-jquery

    聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

    文檔

    Ajax與JSON的一些學習總結(jié)

    Ajax與JSON的一些學習總結(jié):1.1.1 摘要 Ajax技術(shù)的核心是XMLHttpRequest對象(簡稱XHR),可以通過使用XHR對象獲取到服務器的數(shù)據(jù),然后再通過DOM將數(shù)據(jù)插入到頁面中呈現(xiàn)。雖然名字中包含XML,但Ajax通訊與數(shù)據(jù)格式無關(guān),所以我們的數(shù)據(jù)格式可以是XML或JSON等格式。 XMLHt
    推薦度:
    標簽: json 學習心得 ajax
    • 熱門焦點

    最新推薦

    猜你喜歡

    熱門推薦

    專題
    Top
    主站蜘蛛池模板: 国产精品视频第一页| 久久精品国产一区二区电影| 国产精品久久久久久久久久免费| 亚洲av永久无码精品古装片 | 精品国内片67194| 久久丫精品国产亚洲av不卡| 无夜精品久久久久久| 精品无码久久久久久久动漫| 午夜精品视频在线| 国产亚洲精品va在线| 91精品在线看| AV无码精品一区二区三区| 亚洲AV无码国产精品麻豆天美 | …久久精品99久久香蕉国产| 奇米影视7777久久精品| 人妻少妇乱子伦精品| 无码精品一区二区三区在线| 在线观看自拍少妇精品| 亚洲а∨天堂久久精品9966| 久久精品免费大片国产大片| 精品无码一级毛片免费视频观看 | 精品久久久久久中文字幕| 97在线精品视频| 国产成人精品男人的天堂538| 国产成人无码久久久精品一| 精品国产乱码久久久久久1区2区| 乱精品一区字幕二区| 久久夜色精品国产噜噜亚洲AV| 乱色精品无码一区二区国产盗| 久久国产乱子伦免费精品| 国内精品久久久人妻中文字幕| 国产亚洲精品a在线无码| 国产精品白浆在线观看免费| 国产精品99久久免费观看| 国产国拍亚洲精品mv在线观看| 国产成人精品日本亚洲网址| 久久er热视频在这里精品| 97精品国产高清自在线看超| 国产亚洲精品无码专区| 精品视频久久久久| 自拍偷在线精品自拍偷|