ajax 實踐

題目1: ajax 是什么?有什么作用?

ajax是一種技術(shù)方案柴我,但并不是一種新技術(shù)堪伍。它依賴的是現(xiàn)有的CSS/HTML/Javascript锚烦,而其中最核心的依賴是瀏覽器提供的XMLHttpRequest對象,是這個對象使得瀏覽器可以發(fā)出HTTP請求與接收HTTP響應(yīng)帝雇。

所以我用一句話來總結(jié)兩者的關(guān)系:我們使用XMLHttpRequest對象來發(fā)送一個Ajax請求涮俄。

AJAX是對Asynchronous Javascript +XML的簡寫,它的誕生使得向服務(wù)器請求額外的數(shù)據(jù)而不用刷新頁面尸闸。它的優(yōu)缺點如下:

  • 優(yōu)點:

  • 更新數(shù)據(jù)而不需要刷新頁面: 它能在不刷新整個頁面的前提下與服務(wù)器通信維護(hù)數(shù)據(jù)彻亲,由于ajax是按照需求請求數(shù)據(jù),避免發(fā)送那些沒有改變的數(shù)據(jù)吮廉。

  • 異步通信: 它與服務(wù)器使用異步的方式通信苞尝,不會打斷用戶的操作(卡死頁面)。

  • 前后端負(fù)載平衡: 可以將后端服務(wù)器的一些工作轉(zhuǎn)移給客戶端宦芦,利用客戶端限制的能力來處理宙址,減輕了服務(wù)器的負(fù)擔(dān)。

  • 數(shù)據(jù)與呈現(xiàn)分離: 利于分工调卑,降低前后耦合抡砂。

  • 缺點:

  • 瀏覽器歷史記錄的遺失: 在使用AJAX對頁面進(jìn)行改變后,由于并沒有刷新頁面恬涧,沒有改變頁面的訪問歷史注益,當(dāng)用戶想要回到上一個狀態(tài)時,無法使用瀏覽器提供的后退溯捆。

  • AJAX的安全問題: AJAX的出現(xiàn)就像建立起了一直通服務(wù)器的另一條通道丑搔,容易遭受到一些攻擊。

題目2: 前后端開發(fā)聯(lián)調(diào)需要注意哪些事情提揍?后端接口完成前如何 mock 數(shù)據(jù)啤月?

前后端開發(fā)聯(lián)調(diào)的注意事項:

  • 約定接口數(shù)據(jù):有哪些需要傳輸?shù)臄?shù)據(jù),數(shù)據(jù)的類型是什么碳锈?
  • 約定接口名稱:確定好接口的名稱顽冶,接口傳輸?shù)膮?shù),響應(yīng)的數(shù)據(jù)是什么售碳?響應(yīng)數(shù)據(jù)的格式强重。
  • 根據(jù)接口需求整理成文檔绞呈。

后端接口完成前如何 mock 數(shù)據(jù) ?

  • 可以根據(jù)接口文檔间景,使用假數(shù)據(jù)來驗證我們制作的頁面響應(yīng)和接口是否正常佃声。
  • 安裝 xampp 環(huán)境模擬數(shù)據(jù)接收響應(yīng)。
  • 使用 server-mock 來 mock 數(shù)據(jù)倘要。

題目3:點擊按鈕圾亏,使用 ajax 獲取數(shù)據(jù),如何在數(shù)據(jù)到來之前防止重復(fù)點擊?

//用狀態(tài)鎖
var lock = true;        //狀態(tài)鎖默認(rèn)打開
btn = addEventListener("click", function(){
    if(!lock) return;      //如果狀態(tài)鎖為false封拧,則點擊直接return
    lock = false;          // 把狀態(tài)鎖賦值為false
    xhr = onreadystatechange = function (){
         if ( xhr.readyState === 4) {  
              lock = true;    // 數(shù)據(jù)來了之后再把狀態(tài)鎖賦值為 true 志鹃,就可以進(jìn)行下一次點擊請求數(shù)據(jù)
         }
    }
})

題目4:封裝一個 ajax 函數(shù),能通過如下方式調(diào)用泽西。后端在本地使用server-mock來 mock 數(shù)據(jù)

function ajax(opts){ // todo ...}
document.querySelector('#btn').addEventListener('click', function(){ 
    ajax({ url: '/login', //接口地址 
    type: 'get', // 類型曹铃, post 或者 get, 
    data: { username: 'xiaoming', password: 'abcd1234' }, 
    success: function(ret){ 
         console.log(ret); // {status: 0} 
         }, 
    error: function(){ 
         console.log('出錯了')
         }
     })
});

// 封裝ajax函數(shù)
function ajax(opts){
            opts.success = opts.success || function(){};
            opts.error = opts.error || function(){};
            opts.type = opts.type || 'get';
            opts.dataType = opts.dataType || 'json';
            opts.data = opts.data || {};
            var dataStr ='';
            for (var key in opts.data) {
                dataStr += key + '=' + opts.data[key] + '&';
            }
            var dataStr = dataStr.substr(0, dataStr.length - 1);
            var xmlhttp = new XMLHttpRequest();
            xmlhttp.onreadystatechange = function() {
                 if(xmlhttp.readyState === 4){
                    if(xmlhttp.status === 200 || xmlhttp.status === 304){
                        if(opts.dataType === 'text') {
                            opts.onSuccess(xmlhttp.responseText);
                        } 
                        if(opts.dataType === 'json') {
                            var json = JSON.parse(xmlhttp.responseText);
                            opts.success(json);
                        }
                    } else {
                        opts.error();
                    }
                }
            };

            if (opts.type.toLowerCase() === 'post') {
                xmlhttp.open(opts.type, opts.url, true);
                xmlhttp.setRequestHeader("Content-type", "application/x-www-from-urlencoded");
                xmlhttp.send(dataStr);
            }
            if (opts.type.toLowerCase() === 'get') {
                xmlhttp.open(opts.type, opts.url + "?" + dataStr, true);
                xmlhttp.send();
            }


}

題目5:實現(xiàn)加載更多的功能,效果范例133捧杉,后端在本地使用server-mock來模擬數(shù)據(jù))

代碼成功例子截圖:
Paste_Image.png
Paste_Image.png

html代碼:

<!doctype html>
<html>
<head>
    <meta name="name" content="content" charset="utf-8">
    <link rel="stylesheet" href="css/style.css" />
</head>
<body>
  <div id="content">
    <ul id="newsList">     
    </ul>
    <button id="load-more" class="btn">加載更多</button>
  </div>

  <script>
     var  newsList = document.querySelector("#newsList");
     var btn = document.querySelector("#load-more");
     var pageIndex = 0;
     var lock = false;
     btn.addEventListener('click', function(){
        if(lock) return;
        lock = true;
        loadData(function(news){
          renderPage(news);
          lock = false;
          pageIndex += 5;
          
        })
        // 加載數(shù)據(jù)
        function loadData(callback){
          ajax({
            type: 'get',
            url: '/loadMore',
            data: {
              index: pageIndex,
              length: 5
            },
            onSuccess: callback,
            onError: function(){
              console.log('出錯了');
            }
          });
        }
       // 創(chuàng)建代碼節(jié)點
        function renderPage(news){
          var fragment = document.createDocumentFragment();
          for(var i=0; i<news.length; i++){
                node = document.createElement('li');
                node.innerText = news[i];
                fragment.appendChild(node);
              }

              newsList.appendChild(fragment);
        }
       // 封裝 ajax 函數(shù)
        function ajax(opts){
            opts.onSuccess = opts.onSuccess || function(){};
            opts.onError = opts.onError || function(){};
            opts.type = opts.type || 'get';
            opts.dataType = opts.dataType || 'json';
            opts.data = opts.data || {};
            var dataStr ='';
            for (var key in opts.data) {
                dataStr += key + '=' + opts.data[key] + '&';
            }
            var dataStr = dataStr.substr(0, dataStr.length - 1);
            var xmlhttp = new XMLHttpRequest();
            xmlhttp.onreadystatechange = function() {
                 if(xmlhttp.readyState === 4){
                    if(xmlhttp.status === 200 || xmlhttp.status === 304){
                        if(opts.dataType === 'text') {
                            opts.onSuccess(xmlhttp.responseText);
                        } 
                        if(opts.dataType === 'json') {
                            var json = JSON.parse(xmlhttp.responseText);
                            opts.onSuccess(json);
                        }
                    } else {
                        opts.onError();
                    }
                }
            };

            if (opts.type.toLowerCase() === 'post') {
                xmlhttp.open(opts.type, opts.url, true);
                xmlhttp.setRequestHeader("Content-type", "application/x-www-from-urlencoded");
                xmlhttp.send(dataStr);
            }
            if (opts.type.toLowerCase() === 'get') {
                xmlhttp.open(opts.type, opts.url + "?" + dataStr, true);
                xmlhttp.send();
            }
        }
     })
  </script>
</body>
</html>

router.js部分:

app.get('/loadMore', function(req, res){
  var curIdx = req.query.index;
  var len = req.query.length;
  var data = [];

  for(var i=0; i<len; i++){
     data.push('新聞' + (parseInt(curIdx) + i));
  }
    res.send(data);
});

css部分:

ul,
li {
  padding: 0;
  margin: 0;
}    
li {
  list-style: none;  
}
#content {
  width: 600px;
  margin: 0 auto;
}
#newsList > li{
  border: 1px solid #ccc;
  padding: 10px;
  margin: 10px;
}
#newsList > li:hover {
  background-color: #87B7FF;
  color: #fff;
}
.btn {
  width: 100px;
  height: 50px;
  display: block;
  margin: 10px auto;
  color: #fff;
  border: none;
  border-radius: 15px;
  box-shadow: 0 8px #ccc;
  background: #4CAF50;
  text-align: center;
  text-decoration: none;
  outline: none;
  cursor: pointer;
  -webkit-transition-duration: 0.4s; /* Safari */
  transition-duration: 0.4s;
}
.btn:hover {
  background-color: #008CBA; /* Green */
  color: white;
}
.btn:active {
  background-color: #3e8e41;
  box-shadow: 0 5px #666;
  transform: translateY(4px);
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末陕见,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子味抖,更是在濱河造成了極大的恐慌评甜,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件仔涩,死亡現(xiàn)場離奇詭異忍坷,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)熔脂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進(jìn)店門承匣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人锤悄,你說我怎么就攤上這事〖问悖” “怎么了零聚?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長些侍。 經(jīng)常有香客問我隶症,道長,這世上最難降的妖魔是什么岗宣? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任蚂会,我火速辦了婚禮,結(jié)果婚禮上耗式,老公的妹妹穿的比我還像新娘胁住。我一直安慰自己趁猴,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布彪见。 她就那樣靜靜地躺著儡司,像睡著了一般。 火紅的嫁衣襯著肌膚如雪余指。 梳的紋絲不亂的頭發(fā)上捕犬,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天,我揣著相機(jī)與錄音酵镜,去河邊找鬼碉碉。 笑死,一個胖子當(dāng)著我的面吹牛淮韭,可吹牛的內(nèi)容都是我干的垢粮。 我是一名探鬼主播,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼缸濒,長吁一口氣:“原來是場噩夢啊……” “哼足丢!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起庇配,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤斩跌,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后捞慌,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體耀鸦,經(jīng)...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年啸澡,在試婚紗的時候發(fā)現(xiàn)自己被綠了袖订。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,731評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡嗅虏,死狀恐怖洛姑,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情皮服,我是刑警寧澤楞艾,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站龄广,受9級特大地震影響硫眯,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜择同,卻給世界環(huán)境...
    茶點故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一两入、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧敲才,春花似錦裹纳、人聲如沸择葡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽刁岸。三九已至,卻和暖如春她我,著一層夾襖步出監(jiān)牢的瞬間虹曙,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工番舆, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留酝碳,地道東北人。 一個月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓恨狈,卻偏偏與公主長得像只冻,于是被迫代替她去往敵國和親川抡。 傳聞我的和親對象是個殘疾皇子朱嘴,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,629評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 題目1: ajax 是什么变逃?有什么作用? 含義:腳本發(fā)起HTTP通信 作用:傳輸數(shù)據(jù)到服務(wù)器吗氏,監(jiān)聽狀態(tài)碼實現(xiàn)服務(wù)器...
    從前慢pearl閱讀 139評論 0 0
  • 在了解ajax之前,我們先粗略的了解一下http協(xié)議 HTTP協(xié)議 http事務(wù) 一個完整的http請求是怎樣的呢...
    YM雨蒙閱讀 323評論 0 4
  • ajax 是什么芽偏?有什么作用? AJAX的全稱是Asynchronous JavaScript and XML(異...
    cross_王閱讀 334評論 0 0
  • 1- 關(guān)于 ajax 及其作用 Ajax是Asynchronous JavaScript and XML的縮寫弦讽。...
    osborne閱讀 538評論 0 0
  • 2012-5-31 虛受老師講如何引導(dǎo)孩子愛上數(shù)學(xué) 麥蘭污尉,發(fā)了幾道小學(xué)的數(shù)學(xué)題在群里,虛受老師即興傳授了數(shù)學(xué)的學(xué)習(xí)...
    66e1ba940d65閱讀 428評論 0 0