ajax 实践

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

ajax是一种技术方案,但并不是一种新技术。它依赖的是现有的CSS/HTML/Javascript,而其中最核心的依赖是浏览器提供的XMLHttpRequest对象,是这个对象使得浏览器可以发出HTTP请求与接收HTTP响应。

所以我用一句话来总结两者的关系:我们使用XMLHttpRequest对象来发送一个Ajax请求。

AJAX是对Asynchronous Javascript +XML的简写,它的诞生使得向服务器请求额外的数据而不用刷新页面。它的优缺点如下:

  • 优点:

  • 更新数据而不需要刷新页面: 它能在不刷新整个页面的前提下与服务器通信维护数据,由于ajax是按照需求请求数据,避免发送那些没有改变的数据。

  • 异步通信: 它与服务器使用异步的方式通信,不会打断用户的操作(卡死页面)。

  • 前后端负载平衡: 可以将后端服务器的一些工作转移给客户端,利用客户端限制的能力来处理,减轻了服务器的负担。

  • 数据与呈现分离: 利于分工,降低前后耦合。

  • 缺点:

  • 浏览器历史记录的遗失: 在使用AJAX对页面进行改变后,由于并没有刷新页面,没有改变页面的访问历史,当用户想要回到上一个状态时,无法使用浏览器提供的后退。

  • AJAX的安全问题: AJAX的出现就像建立起了一直通服务器的另一条通道,容易遭受到一些攻击。

题目2: 前后端开发联调需要注意哪些事情?后端接口完成前如何 mock 数据?

前后端开发联调的注意事项:

  • 约定接口数据:有哪些需要传输的数据,数据的类型是什么?
  • 约定接口名称:确定好接口的名称,接口传输的参数,响应的数据是什么?响应数据的格式。
  • 根据接口需求整理成文档。

后端接口完成前如何 mock 数据 ?

  • 可以根据接口文档,使用假数据来验证我们制作的页面响应和接口是否正常。
  • 安装 xampp 环境模拟数据接收响应。
  • 使用 server-mock 来 mock 数据。

题目3:点击按钮,使用 ajax 获取数据,如何在数据到来之前防止重复点击?

//用状态锁
var lock = true;        //状态锁默认打开
btn = addEventListener("click", function(){
    if(!lock) return;      //如果状态锁为false,则点击直接return
    lock = false;          // 把状态锁赋值为false
    xhr = onreadystatechange = function (){
         if ( xhr.readyState === 4) {  
              lock = true;    // 数据来了之后再把状态锁赋值为 true ,就可以进行下一次点击请求数据
         }
    }
})

题目4:封装一个 ajax 函数,能通过如下方式调用。后端在本地使用server-mock来 mock 数据

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函数
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:实现加载更多的功能,效果范例133,后端在本地使用server-mock来模拟数据)

代码成功例子截图:
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;
          
        })
        // 加载数据
        function loadData(callback){
          ajax({
            type: 'get',
            url: '/loadMore',
            data: {
              index: pageIndex,
              length: 5
            },
            onSuccess: callback,
            onError: function(){
              console.log('出错了');
            }
          });
        }
       // 创建代码节点
        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 函数
        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);
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,884评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,212评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,351评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,412评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,438评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,127评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,714评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,636评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,173评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,264评论 3 339
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,402评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,073评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,763评论 3 332
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,253评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,382评论 1 271
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,749评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,403评论 2 358

推荐阅读更多精彩内容

  • 题目1: ajax 是什么?有什么作用? 含义:脚本发起HTTP通信 作用:传输数据到服务器,监听状态码实现服务器...
    从前慢pearl阅读 140评论 0 0
  • 在了解ajax之前,我们先粗略的了解一下http协议 HTTP协议 http事务 一个完整的http请求是怎样的呢...
    YM雨蒙阅读 326评论 0 4
  • ajax 是什么?有什么作用? AJAX的全称是Asynchronous JavaScript and XML(异...
    cross_王阅读 334评论 0 0
  • 1- 关于 ajax 及其作用 Ajax是Asynchronous JavaScript and XML的缩写。...
    osborne阅读 540评论 0 0
  • 2012-5-31 虚受老师讲如何引导孩子爱上数学 麦兰,发了几道小学的数学题在群里,虚受老师即兴传授了数学的学习...
    66e1ba940d65阅读 431评论 0 0