美文网首页
js__Ajax__实践

js__Ajax__实践

作者: 好奇而已 | 来源:发表于2017-05-09 18:22 被阅读31次

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

    • Ajax是Asynchronous JavaScript and XML的缩写,这一技术能够向服务器请求额外的数据而无需卸载整个页面.

    • AJAX 在浏览器与 Web 服务器之间使用异步数据传输(HTTP 请求)从服务器获取数据,这里的异步是指脱离当前浏览器页面的请求、加载等单独执行,这意味着可以在不重新加载整个网页的情况下,通过JavaScript接受服务器传来的数据,然后操作DOM将新数据对网页的某部分进行更新,

    • Ajax是一种浏览器和服务器的通讯技术,Ajax不是浏览器自带功能

    • open()方法的第三个参数表示请求采用异步还是同步方式,默认值为true–异步方式

    • 作用
      使用Ajax最直观的感受是向服务器获取新数据不需要刷新页面等待了,良好的用户体验

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

    • 注意点:
    • 约定数据:需要传输的数据以及数据类型;
    • 约定接口:接口名称,请求和响应的格式,请求的参数名称,响应的数据格式;
    • 约定方式 :是get还是post,后端用同样的方式接收发送过来的数据
    • 前后端独立开发,前端向Mock Server发送请求,获取模拟的数据进行开发和测试
    • 如果接口修改了,Mock Server要同步修改
    • 如何 mock ?
      方法一:本地Mock Server做法:前端把Mock Server克隆到本地,开发的时候,开启前端工程服务器和Mock Server,所有的请求都发向本地服务器,获取到Mock数据.
      方法二: 使用nodejs的express框架

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

    • 1.在请求数据方法前引入布尔变量如var isDataArrive = true,
      2.在绑定按钮点击请求数据事件的方法里的开头做次判断,如果发请求前有值(即isDataArrive = ture ),就return,不请求,因为在
      3.在xhr.onreadystatechange方法里的判断xhr.readystate的值===4的方法里引入布尔变量isDataArrive = true,
      4.在发送请求的方法xhr.send()后引入布尔变量isDataArrive = false.
    var check = true;
    btn.addEventListener("click",function(){
        if(!check){
          return;
        }
        var xhr=new XMLHttpRequest()
        xhr.onreadystatechange=function(){
          if(xhr.readyState==4&&(xhr.status==200||xhr.status==304)){
              console.log(xhr.response);
              check = true;
          }   
        }
        xhr.open(method,url,true);
        xhr.send();
        check=false
    })
    

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

    <script>
    //封装的方法
    function ajax(opts){
      var xhr = new XMLHttpRequest()
      xhr.onreadystatechange = function(){
          if(xhr.readyState === 4){
              if(xhr.status === 200 || xhr.status === 304){
                  var results = JSON.parse(xhr.responseText)
                  opts.success('results')
              }else{
                  opts.error()
              }
          }
      }
      var query = '?'
      for (key in opts.data){
          query += key + '=' + opts.data[key] + '&'
          //query = query + key + '=' + opts.data[key] + '&'
          //?username=xiaoming& 遍历第一次
          //?username=xiaoming&password=abcd1234& 第二次
      }
    
      query = query.substr(0, query.length-1)//去除最后一位的&--->?username=xiaoming&password=abcd1234
      xhr.open(opts.type, opts.url+query, true)//配置参数,这里 opts.url+query = '/login?username=xiaoming&password=abcd1234'
      xhr.send()//发生请求
    }
    
    //点击事件
    document.querySelector('#btn').addEventListener('click', function () {
        ajax({
            url: '/login',//接口地址 
            type: 'get', // 类型, post 或者 get, 
            data: {
                username: 'xiaoming',
                password: 'abcd1234'
            },
            success: function (ret) {
                console.log(ret); //ret为xhr.responseText,成功请求到的内容             
            },
            error: function () {
                console.log('出错了')
            }
        })
    });
    
    </script>
    
    
    
    
    

    5:实现加载更多的功能,效果范例,后端在本地使用server-mock来模拟数据

    • 效果
    使用Ajax加载更多

    HTML__CSS部分

    <!DOCTYPE html>
    <html>
    
    <head>
      <meta charset="utf-8" />
      <title>
        加载更多
      </title>
      <style>
        ul,
        li {
          margin: 0;
          padding: 0
        }
    
        #ct li {
          list-style: none;
          border: 1px solid #ccc;
          padding: 10px;
          margin-top: 10px;
          cursor: pointer;
        }
    
        #load-more {
          display: block;
          margin: 10px auto;
          text-align: center;
          cursor: pointer;
        }
    
        .btn {
          display: inline-block;
          height: 40px;
          line-height: 40px;
          width: 80px;
          border: 1px solid #E27272;
          border-radius: 3px;
          text-align: center;
          text-decoration: none;
          color: #E27272;
        }
    
        .btn:hover {
          background: green;
          color: #fff;
        }
    
        #ct>li:hover {
          background-color: pink;
        }
      </style>
    </head>
    
    <body>
      <ul id="ct">
      </ul>
      <a id="load-more" class="btn" href="#">
          加载更多
        </a>
    </body>
    </html>
    

    js部分

    <script>
      var ct = document.querySelector('#ct')
      var btn = document.querySelector('#load-more')
    
      var curIndex = 0  //当前要加载的数据的序号
      var len = 5   // 每次加载多少个数据
      var isLoading = false  //状态锁,用于判断是否在加载数据
    
    
      //点击事件
      btn.addEventListener('click', function (e) {
        e.preventDefault();  //防止点击 a 链接页面跳到顶部
    
        if (isLoading) {
          return   //如果正在请求数据,那这次点击什么都不做
        }
    
        //执行到这里说明 没有正在发出的请求,那后面就可以发请求
        ajax('/loadMore', {
          idx: curIndex,
          len: len
        }, function (data) {
          appendData(data)
          isLoading = false   //数据到来之后 解
          curIndex = curIndex + len  //修改序号,下次要数据就从新序号开始要
          console.log(curIndex)
        })
        isLoading = true   //发请求之前做个标记加锁
    
      })
    
    
      //封装的函数
      function ajax(url, json, onSuccess, onError) {
        var xhr = new XMLHttpRequest()
        var arr = []
        for (key in json) {
          arr.push(key + '=' + json[key])
        }
        url += '?' + arr.join('&')
        xhr.open('get', url)
        xhr.send()
    
        xhr.onload = function () {//若xhr请求成功,就会触发xhr.onreadystatechange和xhr.onload两个事件。 那么我们到底要将成功回调注册在哪个事件中呢?我倾向于 xhr.onload事件,因为xhr.onreadystatechange是每次xhr.readyState变化时都会触发,而不是xhr.readyState=4时才触发
          if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
            onSuccess(JSON.parse(this.response))//this = xhr对象   this.response 是 responseText
          } else {
            onError && onError()
          }
        }
      }
    
    
    
      //封装函数,data 为 JSON.parse(this.response)即响应内容
      function appendData(data) {
        for (var i = 0; i < data.length; i++) {
          var child = document.createElement('li')
          child.innerText = data[i]
          ct.appendChild(child)
        }
      }
    
      function onError() {
        console.log('出错了')
      }
    
    </script>
    
    

    后端部分:router.js

    app.get('/loadMore', function (req, res) {
    
        var curIdx = req.query.idx//通过query去拿,这里的idx对应前端js发生请求的参数idx
        var len = req.query.len
        var data = []
    
        for (var i = 0; i < len; i++) {
            data.push('头条' + (parseInt(curIdx) + i))
        }
    
        res.send(data);
    });
    
    

    相关文章

      网友评论

          本文标题:js__Ajax__实践

          本文链接:https://www.haomeiwen.com/subject/nhsitxtx.html