IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> AJAX专题核心知识 倒计时抢购案例 -> 正文阅读

[JavaScript知识库]AJAX专题核心知识 倒计时抢购案例

AJAX核心知识

所有的思路都在代码中

AJAX:核心 基于 XMLHttpRequest创建HTTP请求

  1. 创建 XHR实例
  2. 打开一个URL地址 【发送前的配置信息等】
    method请求方式 GET/DELETE/head/options… , POST (post/put/patch…)
    GET 和 POST 在官方定义中 没有明确区别的
    但是浏览器或者开发的时候,都有一套约定俗成的规范:

    GET请求 传递给服务器的数据 除请求头以外 要求基于URL问号传参
    POST请求 数据一般是通过请求体传递
    send(“name=zs&age=22”)
    @1 GET传递的信息不如POST多 因为URL有长度限制 [IE 2KB chrome 大概是8KB]
    超过这个长度的信息会被自动截掉 这样导致传递的信息是不完整的
    POST 理论上是没有限制的,但是数据越多,传输速度越慢,越消耗时间,
    这样可能导致浏览器报传输超时的错误,所有我们实际上会自己手动做限制
    @2 GET请求会产生缓存 [浏览器的默认行为,不可控的缓存]:两次请求及以上,请求相同的API接口,
    并且传递的参数也一样,浏览器请求的信息会直接返回,而不是从服务器获取最新的数据!
    open(“GET”, “URL?name=mao&age=22&_”+Math.random())
    在请求URL的末尾设置随机数,以此来清除GET缓存的副作用(不是清除缓存 是不走缓存)
    @3 POST相对于GET来说更安全一些,GTE传递的信息是基于URL末尾拼接,这个随便做一些劫持或者修改,
    都可以直接改了,而POST请求主体信息的劫持,没那么好做,但是 “互联网面前 人人都在裸奔!”
    所以不管是什么请求方式 只要设计安全的信息,都需要手动加密,(所有传递的信息默认情况下都是明文的)

url 请求URL
async 是否采用异步 默认情况下 是true
username 需要的用户名
password 密码

监听请求的过程,在不同阶段做不同的处理(包含获取服务器的响应信息)
@1 ajax的状态 xhr.readyState
ajax的状态
0 未发送 unsend
1 opened 初始化一个请求
2 headers_received 收到请求头信息
3 loading 响应主体信息在处理中(接收响应数据中)
4 done 响应数据收到完毕(响应主体数据已经返回)

  @2 HTTP状态码 xhr.status
    200 OK 
    202 服务器接收 还未处理请求
    204 服务器已处理 但不需要返回响应主体内容
    206 断点续传(用得少)
    301 永久转移(重定向 域名迁移)
    302 暂时转移 (负载均衡)
    304 缓存
    305 用户代理
    400 请求参数有误
    401 未授权
    403 服务器拒绝执行 可能会以响应主体返回原因
    404 地址错误 
    405 请求方式不允许
    408 请求超时
    500 服务器内部错误
    503 服务器超负荷
    505 http版本不支持
  @3 获取响应主体信息
    1. xhr.response 响应的内容 (返回的是什么 就是什么)
    2. xhr.responseText 文本形式
    3. xhr.responseXML xml格式的内容
    4. 文件流格式数据 [buffer / 二进制...]
  @4 获取响应头信息
    1. xhr.getResponseHeader(name) 参数name就是需要获取的请求头名称
    2. xhr.getAllResponseHeaders 直接获取所有请求头
  1. 发送请求 [send中传递的信息 就是设置的请求主体中的信息]
    基于请求主体传递给服务器的数据格式是有要求的
  2. form-data 主要应用于文件的上传 new FormData 或者表单提交
    需要设置请求头的content-type类型是 multipart/form-data
  3. x-www-form-urlencoded 格式的字符串 “name=age&age=22” 和get请求传参格式一样
    请求头的content-type类型也需要更改为 application/x-www-form-urlencoded
    Qs库 npm install qs
    Qs.stringfy/parse 实现对象和urlencoded格式字符串之间的转换
  4. raw 未加工的数据 就是字符串格式
    支持:
    @1 普通字符串 text/plain
    @2 js代码字符串 application/javascript
    @3 JSON字符串 application/json
    @4 xml格式 application/xml
    @…
  5. binary 二进制格式 【buffer 二进制…】
    一般用于文件上传
    图片 image/jp(e)g
    excel application/…
  6. GraphQL
    监听方法:
    onload 信息返回 但是http状态码 不一定是200
    onerror 信息没有返回 什么都拿不到 比如可能是断网了
    onreadystatechange 只要 readyState 属性发生变化 则触发
    xhr 总共有7个可用的方法
/** 
  AJAX:核心 基于 XMLHttpRequest创建HTTP请求
  1. 创建 XHR实例
  2. 打开一个URL地址 【发送前的配置信息等】
    method请求方式 GET/DELETE/head/options... , POST (post/put/patch...)
      GET 和 POST 在官方定义中 没有明确区别的
      但是浏览器或者开发的时候,都有一套约定俗成的规范:
        > GET请求 传递给服务器的数据 除请求头以外 要求基于URL问号传参
        > POST请求 数据一般是通过请求体传递
          send("name=zs&age=22")
      @1 GET传递的信息不如POST多 因为URL有长度限制 [IE 2KB chrome 大概是8KB]
        超过这个长度的信息会被自动截掉 这样导致传递的信息是不完整的
        POST 理论上是没有限制的,但是数据越多,传输速度越慢,越消耗时间,
        这样可能导致浏览器报传输超时的错误,所有我们实际上会自己手动做限制
      @2 GET请求会产生缓存 [浏览器的默认行为,不可控的缓存]:两次请求及以上,请求相同的API接口,
        并且传递的参数也一样,浏览器请求的信息会直接返回,而不是从服务器获取最新的数据!
        open("GET", "URL?name=mao&age=22&_"+Math.random())
        在请求URL的末尾设置随机数,以此来清除GET缓存的副作用(不是清除缓存 是不走缓存)
      @3 POST相对于GET来说更安全一些,GTE传递的信息是基于URL末尾拼接,这个随便做一些劫持或者修改,
      都可以直接改了,而POST请求主体信息的劫持,没那么好做,但是 “互联网面前 人人都在裸奔!”
      所以不管是什么请求方式 只要设计安全的信息,都需要手动加密,(所有传递的信息默认情况下都是明文的)
      
    url 请求URL
    async 是否采用异步 默认情况下 是true
    username 需要的用户名
    password 密码
  监听请求的过程,在不同阶段做不同的处理(包含获取服务器的响应信息)
    @1 ajax的状态 xhr.readyState
      ajax的状态
        0 未发送 unsend
        1 opened 初始化一个请求
        2 headers_received 收到请求头信息
        3 loading 响应主体信息在处理中(接收响应数据中)
        4 done 响应数据收到完毕(响应主体数据已经返回)

      @2 HTTP状态码 xhr.status
        200 OK 
        202 服务器接收 还未处理请求
        204 服务器已处理 但不需要返回响应主体内容
        206 断点续传(用得少)
        301 永久转移(重定向 域名迁移)
        302 暂时转移 (负载均衡)
        304 缓存
        305 用户代理
        400 请求参数有误
        401 未授权
        403 服务器拒绝执行 可能会以响应主体返回原因
        404 地址错误 
        405 请求方式不允许
        408 请求超时
        500 服务器内部错误
        503 服务器超负荷
        505 http版本不支持
      @3 获取响应主体信息
        1. xhr.response 响应的内容 (返回的是什么 就是什么)
        2. xhr.responseText 文本形式
        3. xhr.responseXML xml格式的内容
        4. 文件流格式数据 [buffer / 二进制...]
      @4 获取响应头信息
        1. xhr.getResponseHeader(name) 参数name就是需要获取的请求头名称
        2. xhr.getAllResponseHeaders 直接获取所有请求头
  3. 发送请求 [send中传递的信息 就是设置的请求主体中的信息]
    基于请求主体传递给服务器的数据格式是有要求的
    1. form-data 主要应用于文件的上传 new FormData 或者表单提交
      需要设置请求头的content-type类型是 multipart/form-data
    2. x-www-form-urlencoded 格式的字符串 "name=age&age=22" 和get请求传参格式一样
      请求头的content-type类型也需要更改为 application/x-www-form-urlencoded
      Qs库 npm install qs
      Qs.stringfy/parse 实现对象和urlencoded格式字符串之间的转换
    3. raw 未加工的数据 就是字符串格式
      支持:
        @1 普通字符串 text/plain
        @2 js代码字符串 application/javascript
        @3 JSON字符串 application/json
        @4 xml格式 application/xml
        @...
    4. binary 二进制格式 【buffer 二进制...】
      一般用于文件上传
        图片 image/jp(e)g
        excel application/........
    5. GraphQL
  监听方法:
    onload 信息返回 但是http状态码 不一定是200
    onerror 信息没有返回 什么都拿不到 比如可能是断网了
    onreadystatechange 只要 readyState 属性发生变化 则触发
  xhr 总共有7个可用的方法
*/
let xhr = new XMLHttpRequest;
xhr.open("GET", "./01-data.json");
// 监听请求过程
xhr.onreadystatechange = function () {
  if (xhr.status === 200 && xhr.readyState === 4) {
    console.log(xhr.response)
    console.log(xhr.responseText)
    // console.log(xhr.responseXML)
    console.log(xhr.getResponseHeader("content-type"))
    // console.log(xhr.getAllResponseHeaders())
  }
}
// 发送请求
xhr.send()

倒计时抢购案例

所有的思路都在代码中

样式

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }

    .box {
      width: 400px;
      height: 60px;
      line-height: 60px;
      text-align: center;
      background-color: skyblue;
      margin: 100px auto;
      letter-spacing: 2px;
      font-size: 20px;
    }

    .text {
      color: rgb(211, 19, 19);
      font-weight: 600;
    }
  </style>
</head>

<body>
  <div class="box">距离抢购还剩下:
    <span class="text">00:00:00</span>
  </div>
  <script src="./02-倒计时抢购.js"></script>
</body>

</html>

核心逻辑

const countdownModule = (() => {
  /**
 * 倒计时抢购:两个时间
 *  1. 目标时间 18:00:00
 *  2. 当前时间
 *  目标时间 - 当前时间  = 时间差 (计算时间差中包含多少小时 多少分 多少秒)
 *  每间隔一秒钟  重新获取当前时间 重新计算时间差
 * 
 * 核心问题:
 *   1. 当前时间是不可以获取客户端本地的(因为本地的时间客户可以自己肆意的修改)需要统一获取服务器的时间(响应头的Date)
 *   2. 获取服务器时间会存在时间偏差问题(请求响应是耗时的)
 *      所以可以使用head请求,且在readyState的状态为2的时候就可以拿到时间了
 *     在页面不刷新的情况下,每间隔一秒,不是再次从服务器获取(如果每次都获取,服务器容易崩溃,用户的时间误差也会越大)
 */
  const textBox = document.querySelector(".text");
  let serverTime = 0;
  let targetTime = +new Date() + 1000 * 60 * 60;
  let timer;
  const queryServerTime = function queryServerTime() {
    return new Promise(resolve => {
      const xhr = new XMLHttpRequest;
      xhr.open("head", "./01-data.json");
      xhr.onreadystatechange = function () {
        if (xhr.readyState === 2 && (xhr.status >= 200 && xhr.status < 300)) {
          // 获取的时间是 格林尼治时间 需要转为北京时间 +08:00
          // xhr.getResponseHeader("date")
          // new Date(xhr.getResponseHeader("date")) 转为北京时间
          resolve(+new Date(xhr.getResponseHeader("date")));
          // console.log(new Date(xhr.getResponseHeader("date")));
        }
      }
      xhr.send(null);
    });
  }
  // 倒计时计算
  const computed = () => {
    let diff = targetTime - serverTime;
    let hours, minuter, seconds;
    if (diff <= 0) {
      // 到达抢购时间
      textBox.innerHTML = "00:00:00";
      clearInterval(timer);
      return;
    }
    // 还没到时间
    hours = Math.floor(diff / (1000 * 60 * 60));
    minuter = Math.floor((diff = diff - hours * 1000 * 60 * 60) / (1000 * 60));
    seconds = Math.floor((diff = diff - minuter * 1000 * 60) / 1000);
    textBox.textContent = `${("" + hours).padStart(2, 0)}:${("" + minuter).padStart(2, 0)}:${("" + seconds).padStart(2, 0)}`;
  }
  return {
    async init() {
      // 获取服务器时间
      serverTime = await queryServerTime();
      computed();
      // 设置定时器
      timer = setInterval(() => {
        serverTime += 1000;
        computed();
      }, 1000);
    }
  }
})();
countdownModule.init();
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-10 22:22:38  更:2022-03-10 22:24:46 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 8:02:26-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码