JavaScript-AJAX

http://www.w3school.com.cn/jquery/ajax_ajax.asp

AJAX(Asynchronous JavaScript and XML),最大的優(yōu)點(diǎn)是在不重新加載整個(gè)頁(yè)面的情況下馍佑,可以與服務(wù)器交換數(shù)據(jù)并更新部分網(wǎng)頁(yè)內(nèi)容魁瞪。編寫常規(guī)的AJAX代碼并不容易婚被,因?yàn)椴煌臑g覽器對(duì) AJAX 的實(shí)現(xiàn)并不相同,不過(guò)jQuery為我們解決了這個(gè)難題溉仑。

jQuery AJAX 使用

$.ajax([settings]) 返回其創(chuàng)建的 XMLHttpRequest 對(duì)象吧兔,大多數(shù)情況下你無(wú)需直接操作該函數(shù),除非你需要操作不常用的選項(xiàng)以獲得更多的靈活性优炬。參數(shù)對(duì)象settings可選,參數(shù)中的所有的選項(xiàng)都可以通過(guò)$.ajaxSetup() 函數(shù)來(lái)全局設(shè)置厅贪。

  • global: Boolean 默認(rèn)為true蠢护,表示觸發(fā)全局AJAX事件

  • options: Object 可選,AJAX請(qǐng)求設(shè)置

  • async: Boolean 默認(rèn)為true养涮,表示異步請(qǐng)求

  • cache: Boolean 默認(rèn)為true葵硕,dataType為script和jsonp時(shí)默認(rèn)為false眉抬,false表示不緩存此頁(yè)面

  • ifModified: Boolean 默認(rèn)為false,true表示僅在服務(wù)器數(shù)據(jù)改變時(shí)獲取新數(shù)據(jù)

  • timeout: Number 設(shè)置請(qǐng)求超時(shí)時(shí)間(毫秒)懈凹,此設(shè)置將覆蓋全局設(shè)置

  • traditional: Boolean 如果想要用傳統(tǒng)的方式來(lái)序列化數(shù)據(jù)蜀变,那么就設(shè)置為true

  • processData: Boolean 默認(rèn)為true,true表示通過(guò)data選項(xiàng)傳遞進(jìn)來(lái)的數(shù)據(jù)會(huì)被轉(zhuǎn)化成一個(gè)查詢字符串

  • context: Object 設(shè)置AJAX相關(guān)回調(diào)函數(shù)的上下文介评,也就是回調(diào)函數(shù)內(nèi)的this库北,如果不設(shè)定那么this指向調(diào)用本次AJAX請(qǐng)求時(shí)傳遞的options參數(shù)

  • username: String 用于響應(yīng) HTTP 訪問(wèn)認(rèn)證請(qǐng)求的用戶名

  • password: String 用于響應(yīng) HTTP 訪問(wèn)認(rèn)證請(qǐng)求的密碼

  • contentType: String 默認(rèn)為"application/x-www-form-urlencoded",表示發(fā)送信息至服務(wù)器時(shí)內(nèi)容編碼類型

  • dataType: String 預(yù)期服務(wù)器返回的數(shù)據(jù)類型们陆,如不指定jQuery將自動(dòng)根據(jù)HTTP包MIME信息來(lái)智能判斷寒瓦,可用值:"xml"、"html"坪仇、"script"杂腰、"json"、"jsonp"椅文、"text"

  • type: String 默認(rèn)為GET喂很,可選"POST"或"GET"

  • headers: Object 設(shè)置請(qǐng)求頭

  • url: String 發(fā)送請(qǐng)求的地址,默認(rèn)為當(dāng)前頁(yè)地址

  • data: String 發(fā)送到服務(wù)器的數(shù)據(jù)皆刺、請(qǐng)求參數(shù)恤筛,將自動(dòng)轉(zhuǎn)換為請(qǐng)求字符串格式,processData 選項(xiàng)可禁止此自動(dòng)轉(zhuǎn)換芹橡,GET請(qǐng)求中將附加在URL后

  • jsonp: String 在一個(gè)jsonp請(qǐng)求中重寫回調(diào)函數(shù)的名字毒坛,來(lái)替代在"callback"

  • jsonpCallback: String 為jsonp請(qǐng)求指定一個(gè)回調(diào)函數(shù)名,將用來(lái)取代jQuery自動(dòng)生成的隨機(jī)函數(shù)名林说。想讓瀏覽器緩存GET請(qǐng)求的時(shí)候煎殷,指定這個(gè)回調(diào)函數(shù)名

  • scriptCharset: String 只有當(dāng)請(qǐng)求時(shí)dataType為"jsonp"或"script",并且type是"GET"才會(huì)用于強(qiáng)制修改 charset腿箩。通常只在本地和遠(yuǎn)程的內(nèi)容編碼不同時(shí)使用豪直。

  • xhr: Function 需要返回一個(gè) XMLHttpRequest 對(duì)象,默認(rèn)在 IE 下是 ActiveXObject 而其他情況下是 XMLHttpRequest 珠移。用于重寫或者提供一個(gè)增強(qiáng)的 XMLHttpRequest 對(duì)象弓乙。

  • beforeSend: Function(XMLHttpRequest) 發(fā)送請(qǐng)求前可修改XMLHttpRequest對(duì)象的函數(shù),如添加自定義HTTP頭钧惧。參數(shù)為XMLHttpRequest暇韧。如果返回false可以取消本次ajax請(qǐng)求

  • complete: Function(XMLHttpRequest, TS) 請(qǐng)求完成后回調(diào)函數(shù)(請(qǐng)求成功或失敗之后均調(diào)用),參數(shù)為XMLHttpRequest 對(duì)象和一個(gè)描述請(qǐng)求類型的字符串

  • error: Function(XMLHttpRequest, textStatus, errorThrown) 請(qǐng)求失敗時(shí)調(diào)用此函數(shù)浓瞪,參數(shù)為XMLHttpRequest對(duì)象懈玻、錯(cuò)誤信息、捕獲的異常對(duì)象

  • success: Function(responseData, TS) 請(qǐng)求成功后的回調(diào)函數(shù)乾颁,參數(shù)為根據(jù)dataType參數(shù)進(jìn)行處理后的數(shù)據(jù)和描述狀態(tài)的字符串涂乌。

  • dataFilter: Function(data, type) 給Ajax返回的原始數(shù)據(jù)的進(jìn)行預(yù)處理的函數(shù)艺栈,data是返回的原始數(shù)據(jù),type是dataType參數(shù)

示例如下:

<html>
<head>
<script type="text/javascript" src="/jquery/jquery.js"></script>
<script type="text/javascript">
    $(document).ready(function(){
      $("#b01").click(function(){
        // 同步
        htmlobj=$.ajax({url:"/jquery/test1.txt",async:false});
        $("#myDiv").html(htmlobj.responseText);
        // 異步
        $.ajax({
            url: "/jquery/test1.txt",
            success: function(responseData) {
                $("#myDiv").html(responseData);
            }
        });
      });
    });
</script>
</head>
<body>
<div id="myDiv"><h2>通過(guò) AJAX 改變文本</h2></div>
<button id="b01" type="button">改變內(nèi)容</button>
</body>
</html>

AJAX實(shí)現(xiàn)

function ajax(options) {
    options = options || {};
    options.type = (options.type || "GET").toUpperCase();
    options.dataType = options.dataType || "json";
    var params = formatParams(options.data);
    var xhr;

    //創(chuàng)建 - 第一步
    if (window.XMLHttpRequest) {
        xhr = new XMLHttpRequest();
    } else if(window.ActiveObject) {//IE6及以下
        xhr = new ActiveXObject('Microsoft.XMLHTTP');
    }

    //連接 和 發(fā)送 - 第二步
    if (options.type == "GET") {
        xhr.open("GET", options.url + "?" + params, true);
        xhr.send(null);
    } else if (options.type == "POST") {
        xhr.open("POST", options.url, true);
        //設(shè)置表單提交時(shí)的內(nèi)容類型
        xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        xhr.send(params);
    }

    //接收 - 第三步
    xhr.onreadystatechange = function () {
        if (xhr.readyState == 4) {
            var status = xhr.status;
            if (status >= 200 && status < 300 || status == 304) {
                options.success && options.success(xhr.responseText, xhr.responseXML);
            } else {
                options.error && options.error(status);
            }
        }
    }
}

//格式化參數(shù)
function formatParams(data) {
    var arr = [];
    for (var name in data) {
        arr.push(encodeURIComponent(name) + "=" + encodeURIComponent(data[name]));
    }
    arr.push(("v=" + Math.random()).replace(".", ""));
    return arr.join("&");
}

GET跨域提交表單

前臺(tái)代碼:

<!doctype html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>跨域</title>
        <script src="./jquery.min.js"></script>
        <script>
        function flightHandler(data) {
            console.log('2: ',data)
        }
        window.onload = function() {
            $.ajax({
                url: "http://localhost:9432",
                type: "get", // jsonp必須是get方式湾盒,post不支持湿右,注意
                dataType: "jsonp",
                jsonp: "callback", // 回調(diào)函數(shù)名稱變量名
                jsonpCallback: "flightHandler", // 回調(diào)函數(shù)名稱的值
                data: {param: '參數(shù)'},
                beforeSend: function () {
                    console.log('1');
                },
                success: function (msg) {
                    console.log('3: ',msg);
                },
                error: function (XMLHttpRequest, textStatus, errorThrown) {
                    console.log('4: ',XMLHttpRequest, textStatus, errorThrown);
                }
            });
        };
        </script>
    </head>
    <body>
    </body>
</html>

后臺(tái)代碼:

var http = require('http'),
    fs = require('fs'),
    url=require("url");

http.createServer(function(req, res) {
    var query = url.parse(req.url, true).query;
    var func = query.callback;
    console.log(query);
    var msg = `${func}({"txt": "success"})`;
    res.write(msg);
    res.end();  
}).listen(9432);

運(yùn)行結(jié)果為:

1
2:  {txt: "success"}
3:  {txt: "success"}

POST跨域提交表單

CORS(跨域資源共享,Cross-Origin Resource Sharing)罚勾,定義一種跨域訪問(wèn)的機(jī)制毅人,可以讓AJAX實(shí)現(xiàn)跨域訪問(wèn)。CORS允許一個(gè)域上的網(wǎng)絡(luò)應(yīng)用向另一個(gè)域提交跨域AJAX請(qǐng)求荧库。實(shí)現(xiàn)此功能非常簡(jiǎn)單堰塌,只需由服務(wù)器發(fā)送一個(gè)響應(yīng)標(biāo)頭即可。

header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Origin: http://www.test2.com");

CORS提供了一種跨域請(qǐng)求方案分衫,但沒(méi)有為安全訪問(wèn)提供足夠的保障機(jī)制场刑,如果需要信息的絕對(duì)安全,不要依賴CORS當(dāng)中的權(quán)限制度蚪战,應(yīng)當(dāng)使用更多其它的措施來(lái)保障牵现,比如OAuth2。CORS使用場(chǎng)景:

  • CORS在移動(dòng)終端支持的不錯(cuò)邀桑,可以考慮在移動(dòng)端全面嘗試
  • jsonp是get形式瞎疼,承載的信息量有限,所以信息量較大時(shí)CORS是不二選擇
  • 配合新的JSAPI(fileapi壁畸、xhr2等)一起使用贼急,實(shí)現(xiàn)強(qiáng)大的新體驗(yàn)功能

前臺(tái)代碼:

<!doctype html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>跨域</title>
        <script src="./jquery.min.js"></script>
        <script>
        window.onload = function() {
            $.ajax({
                url: "http://localhost:9432",
                type: "post",
                dataType: "json",
                data: {param: '參數(shù)'},
                success: function (msg) {
                    console.log('3: ',msg);
                },
                error: function (XMLHttpRequest, textStatus, errorThrown) {
                    console.log('4: ',XMLHttpRequest, textStatus, errorThrown);
                }
            });
        };
        </script>
    </head>
    <body>
    </body>
</html>

后臺(tái)代碼:

var http = require('http'),
    fs = require('fs'),
    url=require("url");

http.createServer(function(req, res) {
    res.writeHead(200,{"Access-Control-Allow-Origin":"*"});
    // res.setHeader("Access-Control-Allow-Origin","*");

    // 設(shè)置接收數(shù)據(jù)編碼格式為 UTF-8
    req.setEncoding('utf-8');
    //POST & GET : name=zzl&email=zzl@sina.com
    var postData = "";
    // 數(shù)據(jù)塊接收中
    req.addListener("data", function (postDataChunk) {
        postData += postDataChunk;
    });
    // 數(shù)據(jù)接收完畢,執(zhí)行回調(diào)函數(shù)
    req.addListener("end", function () {
        console.log('數(shù)據(jù)接收完畢');
        //GET & POST  ////解釋表單數(shù)據(jù)部分{name="zzl",email="zzl@sina.com"}
        var params = querystring.parse(postData);
        console.log(params);
    });
    var msg = `{"txt": "success"}`;
    res.write(msg);
    res.end();
}).listen(9432);
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末捏萍,一起剝皮案震驚了整個(gè)濱河市太抓,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌令杈,老刑警劉巖走敌,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異逗噩,居然都是意外死亡掉丽,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門异雁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)捶障,“玉大人,你說(shuō)我怎么就攤上這事片迅〔醒” “怎么了?”我有些...
    開封第一講書人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵柑蛇,是天一觀的道長(zhǎng)芥挣。 經(jīng)常有香客問(wèn)我,道長(zhǎng)耻台,這世上最難降的妖魔是什么空免? 我笑而不...
    開封第一講書人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮盆耽,結(jié)果婚禮上蹋砚,老公的妹妹穿的比我還像新娘。我一直安慰自己摄杂,他們只是感情好坝咐,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著析恢,像睡著了一般墨坚。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上映挂,一...
    開封第一講書人閱讀 51,737評(píng)論 1 305
  • 那天泽篮,我揣著相機(jī)與錄音,去河邊找鬼柑船。 笑死帽撑,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的鞍时。 我是一名探鬼主播亏拉,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼逆巍!你這毒婦竟也來(lái)了及塘?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤蒸苇,失蹤者是張志新(化名)和其女友劉穎磷蛹,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體溪烤,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡味咳,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了檬嘀。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片槽驶。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖鸳兽,靈堂內(nèi)的尸體忽然破棺而出掂铐,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布全陨,位于F島的核電站爆班,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏辱姨。R本人自食惡果不足惜柿菩,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望雨涛。 院中可真熱鬧枢舶,春花似錦、人聲如沸替久。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)蚯根。三九已至后众,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間稼锅,已是汗流浹背吼具。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留矩距,地道東北人拗盒。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像锥债,于是被迫代替她去往敵國(guó)和親陡蝇。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355