前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布

AJAX

作者头像
小胖
发布2018-06-27 16:08:05
2.2K0
发布2018-06-27 16:08:05
举报

浏览器与服务器之间,采用HTTP协议通信。用户在浏览器地址栏键入一个网址,或者通过网页表单向服务器提交内容,这时浏览器就会向服务器发出HTTP请求。

1999年,微软公司发布IE浏览器5.0版,第一次引入新功能:允许JavaScript脚本向服务器发起HTTP请求。这个功能当时并没有引起注意,直到2004年Gmail发布和2005年Google Map发布,才引起广泛重视。2005年2月,AJAX这个词第一次正式提出,指围绕这个功能进行开发的一整套做法。从此,AJAX成为脚本发起HTTP通信的代名词,W3C也在2006年发布了它的国际标准。

具体来说,AJAX包括以下几个步骤。

  1. 创建AJAX对象
  2. 发出HTTP请求
  3. 接收服务器传回的数据
  4. 更新网页数据

概括起来,就是一句话,AJAX通过原生的XMLHttpRequest对象发出HTTP请求,得到服务器返回的数据后,再进行处理。

AJAX可以是同步请求,也可以是异步请求。但是,大多数情况下,特指异步请求。因为同步的Ajax请求,对浏览器有“堵塞效应”。

注意,AJAX只能向同源网址(协议、域名、端口都相同)发出HTTP请求,如果发出跨源请求,就会报错。

1、AJAX 是什么?有什么作用?

  1. AJAX:是对Asynchronous JavaScript and XML的简写,是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。这一技术能够向服务器请求额外的数据而无需从新加载页面。
  2. 作用:传统的网页(不使用 AJAX)如果需要更新内容,必需重载整个网页面。而通过使用ajax可以在后台与服务器进行少量数据交换, 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。

2、Ajax和XMLHttpRequest

Ajax核心的技术是XMLHttpRequest对象(简称XHR)。我们通常将Ajax等同于XMLHttpRequest,但细究起来它们两个是属于不同维度的2个概念。

Ajax:(摘自what is Ajax)AJAX stands for Asynchronous JavaScript and XML. AJAX is a new technique for creating better, faster, and more interactive web applications with the help of XML, HTML, CSS, and Java Script. AJAX is based on the following open standards:

  • Browser-based presentation using HTML and Cascading Style Sheets (CSS).
  • Data is stored in XML format and fetched from the server.
  • Behind-the-scenes data fetches using XMLHttpRequest objects in the browser.
  • JavaScript to make everything happen.

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

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

3、XMLHttpRequest对象

1、什么是XMLHttpRequest?

  • XMLHttpRequest是原生JS的一个内置对象,用来在浏览器与服务器之间传送数据,一旦拿到服务器返回的数据,AJAX不会刷新整个网页,而是只更新相关部分,从而不打断用户正在做的事情。XMLHttpRequestAJAX技术的核心,学习AJAX实质上就是在学习XMLHttpRequest

2、如何创建XMLHttpRequest对象:

  • 一般使用new关键字进行创建,然后赋值给一个变量,如下:
代码语言:javascript
复制
var xhr = new XMLHttpRequest();

4、XMLHttpRequest对象的常用属性

1、readyState

只读属性,表示XMLHttpRequest请求当前所处的状态,共有五个数字值(0,1,2,3,4,5)。

  • 0:表示XMLHttpRequest实例已经生成,但是open()方法还没有被调用。
  • 1:表示已调用open方法,但还未调用send方法(请求还未被发送出去),仍然可以使用setRequestHeader(),设定HTTP请求的头信息。
  • 2:表示send方法已调用,数据已发送,并且服务器接收到了请求。
  • 3:表示服务器正在传输数据。
  • 4:表示数据传输完成。

在通信过程中,每当发生状态变化的时候,readyState属性的值就会发生改变。这个值每一次变化,都会触发readyStateChange事件。

2、status

只读属性,表示本次请求所得到的HTTP状态码,返回一个整数。一般来说,如果通信成功的话,这个状态码是200。常用的有如下几个状态码:

  • 200:OK(正常访问);
  • 301:Moved Permanently(永久移动);
  • 302:Moved temporarily(暂时移动);
  • 304:Not Modified(未修改);
  • 307:Temporary Redirect(暂时重定向);
  • 401:Unauthorized (未授权);
  • 403:Forbidden(禁止访问);
  • 404:Not Found(未找到该网址);
  • 500:Internal Server Error (找到网址但服务器发生错误);

基本上,只有200和304的状态码,表示服务器返回是正常状态。|

3、 statusText

与status属性类似,返回本次请求的状态,不同点在于,status只返回一个数字,而该属性返回一个字符串 ,包含整个状态信息,比如”200 OK“|

4、responseType

responseType属性用来指定服务器返回数据(xhr.response)的类型。可通过对该属性赋值来指定接收的数据类型,默认为字符串,有如下几种数据类型:

  • text:以字符串形式接收数据;
  • json:以json对象形式接收数据;
  • blob:blob对象;
  • ArrayBuffer:ArrayBuffer对象;

5、response、responseText、responseXML

三者都是服务器返回的数据,如果数据不完整或者获取失败,它们的值就为null。

不同点:

  • response返回的是数据的主体部分,可以为任何类型(数组,json,XML,字符串等);
  • responseText返回从服务器接收到的字符串。该属性为只读。如果本次请求没有成功或者数据不完整,该属性就会等于null。如果服务器返回的数据格式是JSON,就可以使用responseText属性;
代码语言:javascript
复制
//返回JSON格式的字符串
var data = ajax.responseText;
//把JSON格式的字符串转换为JavaScript对象
data = JSON.parse(data);
  • responseXML返回从服务器接收到的Document对象,该属性为只读。如果本次请求没有成功,或者数据不完整,或者不能被解析为XML或HTML,该属性等于null。该值返回的数据会被直接解析DOM;

5、XMLHttpRequest对象的常用方法

1、abort()

abort方法用来终止已经发出的HTTP请求。

2、getAllResponseHeaders()

getAllResponseHeaders方法返回服务器发来的所有HTTP头信息。格式为字符串,每个头信息之间使用CRLF分隔,如果没有受到服务器回应,该属性返回null,该方法不需要接受参数。

3、getResponseHeader()

getResponseHeader方法返回HTTP头信息指定字段的值,如果还没有收到服务器回应或者指定字段不存在,则该属性为null。该方法需要接受一个参数,用来返回指定字段的值。

4、open()

XMLHttpRequest对象的open方法用于指定发送HTTP请求的参数,常用的有三个参数:

  • 第一个参数:请求的类型(常用get或者post);
  • 第二个参数是接口名和:这里要分两种情况:
  • get请求时:接口名+请求参数(键值对形式);post请求时:只需要接口名(需要传递的参数写在send方法里);
  • 第三个参数:一个布尔值,指定是否异步(true为异步,false为同步,通常为true,默认为true);

第四和第五个参数:填写用于认证的用户名和密码;

5、send()

send方法用于实际发出HTTP请求。如果不带参数,就表示HTTP请求只包含头信息,也就是只有一个URL,典型例子就是GET请求;如果带有参数,就表示除了头信息,还带有包含具体数据的信息体,典型例子就是POST请求。

如果是POST请求还要在open()之后、send()之前使setRequestHeader方法设置HTTP头信息。

ajax.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

6、setRequestHeader()

setRequestHeader方法用于设置HTTP头信息。该方法必须在open()之后、send()之前调用。

6、XMLHttpRequest对象的事件以及对应的事件监听接口

image.png

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

mock数据指的是在后端开发没有完成时,前端可以通过mock方法搭建本地服务器,模拟后台数据来实现数据交互的效果

前后端开发联调需要注意哪些事情:

  1. 约定数据:有哪些需要传输的数据,数据类型是什么。
  2. 约定接口:确定接口名称以及请求和响应的方法(get or post),请求的参数名称,响应的数据格式。
  3. 根据这些约定整理成接口文档。

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

  1. 根据接口文档,使用假数据来验证制作的网页响应和接口是否正常。
  2. 可以使用server-mock。

3,可以搭建php本地服务器用,php写脚本提供临时数据。

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

利用布尔值设置一个状态锁,在触发ajax前和数据到来的时候布尔值设置为true,是不锁定的;发送数据之后布尔值为false,是锁定的。若重复点击在数据没有到来之前也就是布尔值为true时,会把重复点击忽略。

代码语言:javascript
复制
//利用布尔值作为状态锁
var lock = true; 
btn.addEventListener('click',function(){
   //用户重复点击,数据没有到来之前直接return,忽略重复点击
   if(!lock ){
     return;
   }
   ajax({
     ...
     //数据到来,布尔值设为true
     lock = true; 
   })
   xhr.open(...,...,...);
   xhr.send();
   //发送ajax请求,这时数据还没有到来,布尔值设为false
   lock = false; 
});

9、封装AJAX实现加载更多

这里使用server-mock来mock数据。server-mock是一款nodejs命令行工具,用于搭建web服务器,模拟网站后端,方便前端开发者Mock数据。

index.html

代码语言:javascript
复制
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</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;
    }
  </style>
</head>
<body>
  <ul id="ct">   
  </ul>
  <a id="load-more" class="btn" href="#">
    加载更多
  </a>
  <script>
    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;
       }

       loadData(function(news){
        renderPage(news);     
       })     
    })

    function loadData(callback){
      ajax({
        type: 'get',
        url: '/loadMore',
        data: {
          index: pageIndex,
          length: 5
        },
        onSuccess: callback,
        onError: function(){
          console.log('出错了')
        }
      })
    }

    function renderPage(results){
       var fragment = document.createDocumentFragment();
            for (var i = 0; i < results.length; i++) {
              var node = document.createElement('li');
              node.innerText = results[i];
              fragment.appendChild(node);
            }
            ct.appendChild(fragment)           
    }

    function ajax(options){
      var xhr = new XMLHttpRequest();
      xhr.onreadystatechange = function(){
        if (xhr.readyState === 4) {
          if (xhr.status === 200 || xhr.status === 304) {
            //与后端约定好,传输的数据类型为JSON字符串,JSON.parse()用来把JSON字符串解析为原生JavaScript值
            var results = JSON.parse(xhr.responseText);
            options.onSuccess(results);
            pageIndex = pageIndex + 5;
          }else{
            options.onError();
          }
          //数据到来,布尔值设为true
          isDataArrive = true
        }
      }

      var str = '';
      for(var key in options.data){
        str +=  key + '=' + options.data[key] + '&';   
      }
      str = str.substr(0, str.length-1);

      if(options.type.toLowerCase() === 'get'){
        xhr.open(options.type, options.url + '?' + str, true)
        xhr.send()
      }
      if(options.type.toLowerCase() === 'post'){
        xhr.open('post', options.url, true);
        xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        xhr.send(str);
      }
      //发送ajax请求,这时数据还没有到来,布尔值设为false
      isDataArrive = false;
    }
   
  </script>
</body>
</html>

router.js

代码语言:javascript
复制
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);
})


app.post('/loadMore',function(req,res){

  var curIdx = req.body.index;
  var len= req.body.length;
  var data = [];

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

  res.send(data);
})

image.png

image.png

image.png

每次点击加载更多按钮都会发送一条AJAX请求,数据没回来之前,重复点击会被忽略,数据到来后会渲染到页面上出现5条新闻。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017.10.06 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、AJAX 是什么?有什么作用?
  • 2、Ajax和XMLHttpRequest
  • 3、XMLHttpRequest对象
  • 4、XMLHttpRequest对象的常用属性
  • 5、XMLHttpRequest对象的常用方法
  • 6、XMLHttpRequest对象的事件以及对应的事件监听接口
  • 7、 前后端开发联调需要注意哪些事情?后端接口完成前如何 mock 数据?
  • 8、点击按钮,使用 ajax 获取数据,如何在数据到来之前防止重复点击?
  • 9、封装AJAX实现加载更多
相关产品与服务
命令行工具
腾讯云命令行工具 TCCLI 是管理腾讯云资源的统一工具。使用腾讯云命令行工具,您可以快速调用腾讯云 API 来管理您的腾讯云资源。此外,您还可以基于腾讯云的命令行工具来做自动化和脚本处理,以更多样的方式进行组合和重用。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档