搜索
您的当前位置:首页正文

进阶12 ajax实践

来源:二三娱乐

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

AJAX代表异步JavaScript和XML。简而言之,它是使用 XMLHttpRequest 对象与服务器端脚本进行通信。它可以发送以及接收各种格式的信息,包括JSON,XML,HTML,甚至文本文件。AJAX最吸引人的特性是,它的“异步”性质,这意味着它可以做所有这一切,而不必刷新页面。这让您可以根据用户事件更新页面的某些部分。
AJAX的两个主要功能允许您执行以下操作:

  • 向服务器发出请求,而不重新加载页面
  • 接收和处理服务器中的数据

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

  • 注意事项
    约定数据:有哪些需要传输的数据,数据类型是什么;
    约定接口:确定接口名称及请求和响应的格式,请求的参数名称、响应的数据格式;
    根据这些约定整理成接口文档
  • 如何mock
    1. 将 mock 数据写在代码中。
// $.ajax({
//   url: ‘https://cntchen.github.io/userInfo’,
//   type: 'GET',
//   success: function(dt) {
    var dt = {
      "isSuccess": true,
      "errMsg": "This is error.",
      "data": {
        "userName": "Cntchen",
        "about": "FE"
      },
    };
    if (dt.isSuccess) {
      render(dt.data);
    } else {
      console.log(dt.errMsg);
    }
//   },
//   fail: function() {}
// });

优点:可以快速修改数据
缺点:无法模拟异步的网络请求,无法测试网络异常;联调前需要做较多改动,增加最终上真实环境的切换成本。接口文档变化需要手动更新
2.搭建本地服务器
3.使用在线mock服务,比如

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

var isDareArrive= ture;
btn.addEventListener("click",function(){
    if(!isDareArrive){
        return  //数据没到就return退出
    }
    var xhr = new XMLHttpRequest()
    xhr.onreadystatechange = function(){
        if(xhr.readystate === 4){
            if(xhr.readystate === 200||xhr.readystate === 304){
                //dosomething
            }    
            isDareArrive= ture;//状态为4可以解锁
        }         
    }       
    xhr.open('get','/index?length',true)
    xhr.send()
    isDareArrive=fause;//数据没到就不发请求
})

使用状态锁

var  lock=false,
       btn = document.qureySelector('#btn');
btn.addEventListener('click', function(){
    if(lock){
        return;
    }else{
        lock=true;
        ajax({
            ....
            lock=false   //收到响应之后才把false赋值给lock
        })
    }
})

题目4:实现加载更多的功能, 。代码提交到 github

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>加载更多</title>
  <style>
    *{
      margin: 0;
      padding: 0;
    }
     #ct li{
      list-style:none;
      border: 1px solid #ccc;
      padding: 10px;
      margin-top: 10px;
      cursor:pointer;
    
    }
    #ct li:hover{
        background-color: green;
    }
    #load-more{
      display: block;
      margin: 10px auto;
      text-align: center;
      cursor: pointer;
    }
    /*#load-more img{
      width: 40px;
      height: 40px;
    }*/
    .btn{
      display: inline-block;
      height: 40px;
      line-height: 40px;
      width: 80px;
      border: 1px solid #da6969;
      border-radius: 3px;
      text-align: center;
      text-decoration: none;
      color: #E27272;
    }
    .btn:hover{
      background: #3aca46;
      color: #fff;
    }
  </style>
</head>
<body>
  <ul id ="ct">
  </ul>
  <!-- <a href="javascript:void(0)"></a> undefined不跳转-->
  <a href="#" id="load-more" class= "btn">加载更多</a>
</body>

<script>
  //获取a链接
  var btn = document.querySelector("#load-more")
  var ct = document.querySelector("#ct")
  var pageIndex = 0
  //网速特别慢的时候,在数据到来之前防止重复点击?
  var isDataArrive = true
  btn.addEventListener("click",function(e){
    e.preventDefault()
    if(!isDataArrive){
      return;
    }
    var xhr = new XMLHttpRequest()
    xhr.onreadystatechange = function(){
      if (xhr.readyState === 4) {
        if (xhr.status === 200 || xhr.status === 304) {
          var result = JSON.parse(xhr.responseText)
          var fragment = document.createDocumentFragment()
          for (var i = 0; i < result.length; i++) {
            var node = document.createElement("li")
            node.innerText = result[i]
            fragment.appendChild(node)
          }
          //插入li
          ct.appendChild(fragment)
          //数字每次变化5
          pageIndex += 5
        }else{
          alert("出错啦")
        }
        isDataArrive = true
      }
    } 
    xhr.open("get","/loadMore?index="+pageIndex+"&length=5",true)
    xhr.send()
    isDataArrive = false
  })
</script>
</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);
});

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

  function ajax(opts) {
    var xmlhttp;
    if(window.XMLHttpRequest) {           //IE7+,chrome,Safari,Opera,Firefox
      xmlhttp = new XMLHttpRequest();
    } else {
      xmlhttp = new AcitveXObject("Microsoft.XMLHTTP");  //IE5,IE6
    }
    xmlhttp.onreadystatechange = function() {
      if(xmlhttp.readyState == 4 && xmlhttp.status == 200) {
        var json = JSON.parse(xmlhttp.responseText);
        opts.success(json);
      }
      if(xmlhttp.status == 404) {
        opts.error();
      }
    }
    var dataStr= '';
    for(var key in opts.data) {
      dataStr += key + '=' + opts.data[key] + '&';
    }
    dataStr = dataStr.substr(0,dataStr.length-1);
    if(opts.type.toLowerCase() == 'get') {
      xmlhttp.open(opts.type, opts.url + '?' + dataStr, true);
      xmlhttp.send();
    }
    if(opts.type.toLowerCase() == 'post') {
      xmlhttp.open(opts.type, opts.url, true);
      xmlhttp.setRequestHeader("Content-type", 
      xmlhttp.send(dataStr);
    }
  }

推荐文章

Top