ajax 的前世今生

一、ajax基础

浏览器的技术
ajax Asynchronous javascript and xml

  • xml: 是可扩展标记语言,和html一样,可以清楚的表示层级。在ajax刚刚兴起的时候,为了表达数据的结构和层次,数据结构多是使用xml;
  • 现在都是json,json也可以表达数据结构;
    JSON.parse() // json格式字符串转对象
    JSON.stringify() // 对象转JSON格式的字符串
  • 现在的前端都是前后端分离的,即前端负责数据的绑定和维护;
  • 服务端渲染和全局刷新

在很久以前,没有ajax之前,都是前后端不分离的;前后端不分离是前端写好html+css结构,然后把html交给后端,然后利用服务端技术从服务器的数据库中把数据查出来,然后绑定到页面中,然后把绑定好数据的页面直接返回给浏览器,就是说浏览器拿的就是绑定好数据的页面html(服务端渲染SSR(Server-Side-Rendering));

但是这么干有一个问题,如果我这个页面中只有一部分内容是动态绑定的,如果我需要看到这部分内容,就需要刷新整个页面重新获取才行,因为绑定数据只有在服务器上才能进行。这种体验很不好,这种刷新整个页面获取数据的方式称为全局刷新;

  • 前后端分离

后来ajax诞生了,ajax可以直接从服务器获取数据而不用刷新整个页面;发送一个ajax请求,等到请求结束后把数据通过前端手段把数据绑定到页面中(动态创建dom+appendChild或者字符串拼接+innerHTML)。这种用ajax渲染数据的方式是局部刷新的。

  • ajax 的实例是可以向服务器发送请求的;

使用ajax

  1. 创建一个ajax实例对象
    let xhr = new XMLHttpRequest();
  1. 可以通过XMLHttpRequest原型上的open方法打开一个路径
    xhr.open('get', 'https://www.easy-mock.com/mock/xxx95ef4e9dd1a28c/example/myfirstmock', true);

open方法的参数:
http-method: GET POST
url
async: true 表示异步,false表示同步

  1. 监听ajax实例的onreadystatechange事件,当ajax发送请求时,会触发这个事件行为
 xhr.onreadystatechange = function () {
   如果ajax是异步执行的,这个函数会执行三次,三次的readyState分别为x
   console.log(xhr.readyState); 2  3  4

   为了确定拿到数据,我们不仅判断xhr.readyState 判断,还需要根据xhr.status来判断,xhr使用的就是http status,表示当前请求的状态;

  if (xhr.readyState === 4 && /^2\d{2}/.test(xhr.status)) {
     xhr.readyState 为4表示ajax请求完成,xhr.status 是一个以2开头的三位数,表示请求成功,所以可以在获取服务端返回的数据
  }
};

4.发送请求

    xhr.send(); // send方法还可以传递参数

xhr.readyState 表示当前ajax实例对象的所处的状态
0: 创建了一个ajax实例对象
1: 已经调用open方法,打开了路径
2: 客户端已经接收到服务端的信息(如果需要获取头信息中某些内容,可以在readyState为2时获取就可以)
3: 客户端正在接收响应主体的数据
4: 客户端已经全部接收服务端的数据

二、ajax的请求方式

    let xhr = new XMLHttpRequest();
    xhr.open('get', 'aside.json', true);

    xhr.onreadystatechange = function () {
        if (xhr.readyState === 4 && /^2\d{2}/.test(xhr.status)) {
        console.log(xhr.responseText);
        }
    };

    xhr.send(JSON.stringify({username: 'mabin', pwd: '1233456'}));
  • xhr.open() 方法的第一个参数用于指定http-method,即http的请求方式:

一般接口的请求方式由服务端提供,而且会在接口文档中说明

常见的请求方式:

=> GET: 一般用于从服务端获取数据,但是也可以向服务器传递少量的数据;
get请求方式的特点

1.向服务器传递数据的方式:通过向接口末尾添加问号传参的方式传递,如: aside.json?name=mabinpwd=123456
2.由于浏览器的url地址是有长度限制的,IE的url一般不超过2k,谷歌的一般在8k,超过的部分会自动被截掉,所以get请求传递的数据很小
3.参数直接暴露在url中,安全性低;
4.get请求容易产生缓存,为了防止缓存,一般在url末尾拼接一个随机数或者时间戳,因为浏览器发现url变化了,就会重新请求而不是使用之前已经缓存的数据;

=> POST 一般用于把数据传递给服务器或者传递大量的数据时

1.post 把需要传递给服务器的数据放在请求体中传递给服务器
2.由于post数据放在请求体中,大小没有限制
3.post 传递数据时把数据放在请求体中的,相对于get而言比较安全
4.post 请求不会默认走缓存

其他请求方式

+DELETE: 删除数据
+HEAD: 获取响应头,不需要响应体
+PUT: 修改某些内容
+OPTIONS: 查询服务器的支持的http请求方式
+TRACE: 回显服务器收到的请求,一般用于测试
+…

三、ajax的同步和异步

  • js是单线程的:每次只能执行一个任务
  • 浏览器是多线程的,可以同时执行多个任务;
    let data = null;

    let xhr = new XMLHttpRequest();

    xhr.open('get', 'aside.json', true);

    xhr.onreadystatechange = function () {
      console.log(xhr.readyState); // false 时只输出 4
      console.log(xhr.readyState); // true 时输出2 3 4
      data = xhr.responseText;
    };

    xhr.send();

    function bindHTML(data) {
      // 绑定html的方法
    }

为什么会有异步的ajax?

  • 如果页面中有5个请求
    // 1. 1s
    // 2. 2s
    // 3. 3s
    // 4. 4s
    // 5. 5s
  • 如果使用同步的,同步任务都是阻塞的,上一个执行不完下一个不能开始,如果这些接口没有必然关系,用户需要15s才能看到,这个用户体验很不好。
  • 如果使用异步的,第一个发出后随即就开始第二个,然后第三个,因为异步不是阻塞的,后面的不用等待前面的完成(这样子看起来很像同时发送了5个请求),这样一来用时5s就可以了

所以一般情况下ajax使用异步的;

  • 但是使用异步的也有一个问题,如果这5个接口是互相依赖的,比如第二个依赖第一个返回的数据,第三个依赖第二个返回的数据这种情况使用异步,顺序是无法保证的,因为异步任务是谁先到达执行条件谁先执行;

四、jq的ajax

使用原生的ajax把用户名和密码使用post的请求发方式发送到aside.json
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <section>
      <label for="uName">用户名:</label>
      <input type="text" id="uName">
    </section>
    <section>
       <label for="pwd">密码:</label>
       <input type="text" id="pwd">
    </section>
    <section>
       <button id="submit">登录</button>
    </section>

    <script src="js/jquery-3.2.1.js"></script>
    <script src="js/4-jq的ajax.js"></script>
    </body>
    </html>
原生js代码:
  • 获取元素
    let uName = document.getElementById('uName');
    let pwd = document.getElementById('pwd');

    let uNameValue = uName.value;
    let pwdValue = pwd.value;
    let btn = document.getElementById('submit');
  • 原生js
    btn.onclick = function () {
    let xhr = new XMLHttpRequest();
    xhr.open('post', 'aside.json', true);
    xhr.onreadystatechange = function () {
       if (xhr.readyState === 4 && xhr.status === 200) {
       console.log('oh yeach');
       }
    };
    // 注意post请求只能发送字符串类型的数据,一边情况下会使用json格式的字符串
    xhr.send(JSON.stringify({
       username: uNameValue,
       pwd: pwdValue
     }));
    };
使用jq的ajax
    $.ajax({
       url: 'aside.json',
       type: 'post',
       dataType: 'json',
       cache: false,
       async: true,
       data: {
            username: uNameValue,
            pwd: pwdValue
        },
        error(err) {
             console.log(err)
        },
        success (data) {
            console.log(data)
        }
    });

参数详解
url: 请求路径
type: 请求方式
dataType: 数据类型json
async: true 默认异步
cache: false 禁用缓存
error: 请求失败时执行的回调,参数是具体的报错信息
success: 请求成功执行的回调,参数是服务端返回的数据

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值