九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
Ajax與JSON的一些總結(jié)

1.1.1 摘要

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

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

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

本文目錄

1.1.2 正文

XMLHttpRequest是一個(gè)JavaScript對(duì)象,它是由微軟設(shè)計(jì),并且被Mozilla、Apple和Google采納,W3C正在標(biāo)準(zhǔn)化它。它提供了一種簡(jiǎn)單的方法來(lái)檢索URL中的數(shù)據(jù)。

我們要?jiǎng)?chuàng)建一個(gè)XMLHttpRequest實(shí)例,只需new一個(gè)就OK了:

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

也許有人會(huì)說(shuō):“這可不行啊!IE6不支持原始的XHR對(duì)象”,確實(shí)是這樣,我們?cè)诤竺鎸?huì)介紹支持IE6或更老版本創(chuàng)建XHR對(duì)象的方法。

XMLHttpRequest的用法

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

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

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

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

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

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

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

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

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

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的同步請(qǐng)求,如果我們發(fā)送異步請(qǐng)求,那么在請(qǐng)求過(guò)程中javascript代碼會(huì)繼續(xù)執(zhí)行,這時(shí)可以通過(guò)readyState屬性判斷請(qǐng)求的狀態(tài),當(dāng)readyState = 4時(shí),表示收到全部響應(yīng)數(shù)據(jù),屬性值的定義如下:

readyState值

描述

0

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

1

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

2

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

3

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

4

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

表1 readyState屬性值

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

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

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

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同源請(qǐng)求

現(xiàn)在我們對(duì)Ajax的請(qǐng)求實(shí)現(xiàn)有了初步的了解,接下來(lái)我們將通過(guò)具體的例子說(shuō)明Ajax請(qǐng)求的應(yīng)用場(chǎng)合和局限。

在日常網(wǎng)絡(luò)生活中,我們?cè)跒g覽器的地址中輸入要訪問(wèn)的URL并且回車,瀏覽器會(huì)向服務(wù)器發(fā)送請(qǐng)求,當(dāng)服務(wù)器收到請(qǐng)求后,把相應(yīng)的請(qǐng)求頁(yè)面發(fā)送回瀏覽器,我們會(huì)發(fā)現(xiàn)頁(yè)面大部分加載完畢,有些還沒(méi)有加載完畢??偟脕?lái)說(shuō),采用異步加載方式不會(huì)影響已加載完畢的頁(yè)面瀏覽,我們可以通過(guò)Ajax實(shí)現(xiàn)異步加載。

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

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

/// /// The product datatable dao./// public class ProductDao{    ///     /// Initializes a new instance of the  class.    ///     public ProductDao()    {    }    ///     /// Gets or sets the product id.    ///     public int Id { get; set; }    ///     /// Gets or sets the product name.    ///     public string Name { get; set; }    ///     /// Gets or sets the product serial number.    ///     public string SerialNumber { get; set; }    ///     /// Gets or sets the product qty.    ///     public short Qty { get; set; }}

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

接下來(lái),讓我們實(shí)現(xiàn)Product表的數(shù)據(jù)庫(kù)操作類。

/// /// Product table data access manager./// public class ProductManager{    ///     /// The query sql.    ///     private const string Query =         "SELECT ProductID, Name, ProductNumber, SafetyStockLevel FROM Production.Product";    ///     /// Stores the object of  into list.    ///     private IList<ProductDao> _products = new List<ProductDao>();    ///     /// Gets all products in product table.    ///     ///     /// The list of  object.    ///     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;    }}

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

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

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

一般處理程序適用場(chǎng)合:

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

圖1一般處理程序

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

<%@ WebHandler Language="C#" Class="ProductInfo" %>using System.Runtime.Serialization.Json;using System.Web;using ASP.App_Code;/// /// The product data handler./// public class ProductInfo : IHttpHandler {        public void ProcessRequest (HttpContext context) {        context.Response.ContentType = "application/json";        // Creates a  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類實(shí)現(xiàn)了IHttpHandler接口,該接口包含一個(gè)方法ProcessRequest()方法和一個(gè)屬性IsReusable。ProcessRequest()方法用于處理入站的Http請(qǐng)求。在默認(rèn)情況下,ProductInfo類會(huì)把內(nèi)容類型改為application/json,然后我們把數(shù)據(jù)通過(guò)JSON格式寫入輸入流中;IsReusable屬性表示相同的處理程序是否可以用于多個(gè)請(qǐng)求,這里我們?cè)O(shè)置為false,如果為了提高性能也可以設(shè)置為true。

如下圖所示,我們通過(guò)ProductInfo類成功地實(shí)現(xiàn)獲取數(shù)據(jù)到響應(yīng)流中,并且以JSON格式顯示出來(lái)。

圖2 Http請(qǐng)求

當(dāng)我們請(qǐng)求ProductInfo時(shí), 首先它會(huì)調(diào)用ProcessRequest()方法,接著調(diào)用GetAllProducts()方法從數(shù)據(jù)庫(kù)中獲取數(shù)據(jù),然后把數(shù)據(jù)通過(guò)JSON格式寫入到響應(yīng)流中。

現(xiàn)在,我們已經(jīng)成功地把數(shù)據(jù)通過(guò)JSON格式寫入到響應(yīng)流當(dāng)中,接著我們將通過(guò)Ajax方式請(qǐng)求數(shù)據(jù)并且把數(shù)據(jù)顯示到頁(yè)面中。

首先,我們定義方法createXHR()用來(lái)創(chuàng)建XMLHttpRequest對(duì)象,前面我們提到IE6或者更老的版本不支持XMLHttpRequest()方法來(lái)創(chuàng)建XMLHttpRequest對(duì)象,所以我們要在createXHR()方法中,增加判斷當(dāng)前瀏覽器是否IE6或更老的版本,如果是,就要通過(guò)MSXML庫(kù)的一個(gè)ActiveX對(duì)象實(shí)現(xiàn)。因此,在IE中可能遇到三種不同版本的XHR對(duì)象(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();});

前面我們定義了一個(gè)比較通用的方法用來(lái)創(chuàng)建XMLHttpRequest對(duì)象,并且它支持IE6或更老版本創(chuàng)建XMLHttpRequest對(duì)象,接下來(lái)我們將通過(guò)Ajax方法請(qǐng)求數(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);    }}

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

圖3 Ajax請(qǐng)求結(jié)果

現(xiàn)在,我們成功地把數(shù)據(jù)輸出到頁(yè)面當(dāng)中,也許用戶還會(huì)覺(jué)得用戶體驗(yàn)不好,那么我們給就該頁(yè)面增加CSS樣式。

由于時(shí)間的關(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;}

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

圖4 Ajax請(qǐng)求結(jié)果

同源策略與跨源策略

上面我們獲取頁(yè)面和數(shù)據(jù)都是在同源請(qǐng)求情況下,也就是說(shuō),客戶端瀏覽器請(qǐng)求的頁(yè)面和數(shù)據(jù)都是屬于同一域名、同一端口同協(xié)議

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

圖5同源請(qǐng)求過(guò)程

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

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

圖6跨源請(qǐng)求過(guò)程

大家注意到同源請(qǐng)求中我們使用的是JSON格式,但在跨源請(qǐng)求中卻是使用JSONP,這時(shí)大家可能有點(diǎn)困惑,坦然我剛開始學(xué)習(xí)的時(shí)候也是這樣的。

首先我們必須理解JSON和JSONP的區(qū)別:JSON是一種數(shù)據(jù)格式,而JSONP像是通過(guò)一個(gè)方法名來(lái)封裝JSON格式;由于瀏覽器允許跨源請(qǐng)求

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Ajax GET請(qǐng)求應(yīng)用
用 AJAX 構(gòu)建支持實(shí)時(shí)驗(yàn)證的 Web 應(yīng)用程序
原生JavaScript手寫Ajax
AJAX優(yōu)勢(shì)、跨域方案及JSON數(shù)據(jù)格式和瀏覽器中JSON對(duì)象
Ajax調(diào)用WebService(一)
前端跨域請(qǐng)求原理及實(shí)踐
更多類似文章 >>
生活服務(wù)
熱點(diǎn)新聞
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服