发送 AJAX 请求

  1. 第一步:创建一个 XHR 对象:不兼容 XMLHttpRequest 的浏览器 (IE6) 使用 ActiveXObject 创建;
  2. 第二步:打开请求连接(配置请求信息):
    // method 请求方式
    // url 请求地址
    // async 是否为异步请求,默认是 true 异步
    // user-name, user-pass 向服务器发送请求所携带的用户名密码(一般不用)
    xhr.open(method, url, async, user-name, user-pass);
    
  3. 第三步:监听请求状态,在不同状态中做不同的事情;
  4. 第四步:发送 AJAX 请求;

XHR 的属性

属性 描述
xhr.response 响应体数据,类型取决于 responseType 的指定
xhr.status 响应状态码值,比如 200404 ----标识着请求成功或者失败
xhr.statusText 响应状态文本
xhr.timeout 指定请求超时时间,默认为 0 代表没有限制
xhr.withCredentials 值为 true:跨域资源共享中,允许携带资源凭证
xhr.readyState 表示请求状态:
0 创建完 XHR
1 已经完成 OPEN 操作
2 服务器已经把响应头信息返回了
3 响应主体正在返回中
4 响应主体已经返回

XHR 的方法

方法 描述
xhr.abort() 强制中断请求
xhr.getAllResponseHeaders() 获取所有请求头
xhr.getResponseHeader() 获取请求头
xhr.setRequestHeader() 设置请求头(属性值不能是中文和特殊字符)
xhr.open(method,url[,async]) 初始化一个请求
xhr.overrideMimeType() 重写资源类型
xhr.send() 发送请求

XHR 的事件

方法 描述
load 在接收到完整的响应数据时触发
readystatechange 每当 readyState 属性改变时,就会调用该函数
error 在请求发生错误时触发

HTTP 请求

请求 描述
GET 客户端都可以把信息传递给服务器,服务器也可以把信息返回给客户端,只不过 GET 偏向于拿
DELETE 删除,一般代指删除服务器上指定的文件
HEAD 只获取响应头的信息,不获取响应主体内容
OPTIONS 试探性请求,在 CORS 跨域请求中,所以正常请求发送前,先发送一个试探请求,验证是否可以和服务器正常的建立连接
POST 客户端都可以把信息传递给服务器,服务器也可以把信息返回给客户端,POST 偏向于给
PUT 新增,一般代指向服务器中新增文件

HTTP 状态码 xhr.status

  1. 2 开头的状态码(成功类)

  2. 3 开头的状态码(重定向)

  3. 4 开头的状态码(客户端错误)

  4. 5 开头的状态码(服务器错误)

状态码 描述
200 服务器已成功处理了请求
202 服务器已接受请求,但尚未处理
301 永久性重定向,表示资源已被分配了新的 URL
302 临时性重定向,表示资源临时被分配了新的 URL
303 表示资源存在另一个 URL ,用 GET 方法获取资源
304 自从上次请求后,请求网页未修改过,服务器返回此响应时,不会返回网页内容
400 服务器不理解请求的语法
401 表示发送的请求需要有通过 HTTP 认证的认证信息
403 服务器拒绝请求
404 服务器找不到请求网页
500 服务器遇到错误,无法完成请求
503 表示服务器处于停机维护或超负载,无法处理请求

Content-Type 详解

  1. Content-Type 即是 Internet Media Type 互联网媒体类型,也叫做 MIME 类型,在互联网中有成百上千中不同的数据类型,HTTP 在传输数据对象时会为他们打上称为 MIME 的数据格式标签,用于区分数据类型;

  2. HTTP 协议消息头中,使用 Content-Type 来表示请求和响应中的媒体类型信息,来告诉服务端如何处理请求的数据,以及告诉客户端(一般是浏览器)如何解析响应的数据,比如显示图片,解析并展示 html 等等;

Content-Type 格式

Content-Type 的格式:Content-Type:type/subtype;parameter

  1. type:主类型,任意的字符串,如 text 如果是 * 号代表所有;
  2. subtype:子类型,任意的字符串,如 html 如果是 * 号代表所有,用 / 与主类型隔开;
  3. parameter:可选参数,如 charsetboundary 等;

常见 Content-Type

Content-Type 描述
application/x-www-form-urlencoded 数据按照 name=zhangsan&age=20 的方式进行编码,非字母或数字的字符会被
进行 URL 转码
multipart/form-data 它支持文件的传输,并且它的传输数据放在 request-payload 里,并且以 bounday
进行分隔
application/json 消息主体是序列化后的 JSON 字符串

面试题

倒计时抢购

  1. 如何从服务器获取时间,以及存在的问题:

    • 可以基于 ajax 向服务器发送请求,服务器返回的响应头中包含了服务器时间(GMT 格林威治时间,new Date([转换的时间] 转换为北京时间 ));
    • 由于网络传送存在时差,导致客户端接收到的服务器时间和真实时间存在偏差,当响应头信息返回(AJAX 状态为 2 的时候),获取时间即可,HTTP 传输中的 HEAD 请求方式,就是只获取响应头的信息;
    • 获取当前客户端本地的时间 (但是这个时间客户可以修改自己本地的时间):真实项目中只能做一些参考的工作,不能做严谨的校验,严格校验的情况下,需要的时间是从服务器获取的;
  2. 示例代码:

    async function init() {
    let serverTime = await queryServerTime(), // 获取服务器时间
        targetTime = new Date('2020/02/25 20:49:30'), // 目标时间
        autoTimer = null; // 定时器
    
    // 计算时间差
    function computed() {
      let spanTime = targetTime - serverTime;
      if (spanTime <= 0) {
        // 已经到抢购时间了
        spanBox.innerHTML = `00:00:00`;
        clearInterval(autoTimer);
        return;
      }
        let hours = Math.floor(spanTime / (60 * 60 * 1000));
        spanTime = spanTime - hours * 60 * 60 * 1000;
    
        let minutes = Math.floor(spanTime / (60 * 1000));
        spanTime = spanTime - minutes * 60 * 1000;
    
        let seconds = Math.floor(spanTime / 1000);
        hours = hours < 10 ? '0' + hours : hours;
    
        minutes = minutes < 10 ? '0' + minutes : minutes;
        seconds = seconds < 10 ? '0' + seconds : seconds;
    
        spanBox.innerHTML = `${hours}:${minutes}:${seconds}`;
      }
      computed();
    
      // 间隔 1S 后重新计算一次
      autoTimer = setInterval(async _ => {
        // 应该重新从服务器获取时间(但是这样有很大延迟和服务器的压力太大了)
        // serverTime = await queryServerTime();
    
        // 可以基于第一次获取的时间,在原来的基础上,让其自动累加 1000MS 即可
        serverTime = new Date(serverTime.getTime() + 1000);
        computed();
      }, 1000);
    }
    
    init();
    

readyState 变化几次

  1. 示例代码

    JavaScript
    JavaScript
    JavaScript
    // 示例 1
    let xhr = new XMLHttpRequest;
    xhr.open('get', './js/fastclick.js', true); // open 执行完:readyState 为 1
    
    // 异步:在 SEND 后,会把这个请求的任务放在 EventQueue 中(宏任务)
    xhr.send();
    
    // 同步代码,绑定之前 readyState 为 1
    xhr.onreadystatechange = function () {
      console.log(xhr.readyState); //=>2.3.4
    };
    
    // 示例 2
    let xhr = new XMLHttpRequest;
    xhr.open('get', './js/fastclick.js', false); // open 执行完:readyState 为 1
    
    xhr.send();
    
    // 同步代码 send 执行完,readyState 为 4
    xhr.onreadystatechange = function () {
      // readyState 绑定之后是 4,一直没有变化,不触发事件
      console.log(xhr.readyState);
    };
    
    // 示例 3
    let xhr = new XMLHttpRequest;
    xhr.open('get', './js/fastclick.js', false); // open 执行完:readyState 为 1
    
    // 同步:此时绑定 readyState 为 1
    xhr.onreadystatechange = function () {
        // 绑定时 readyState 为 1,send 执行完 readyState 为 4,readyState 有变化 触发事件
        console.log(xhr.readyState); //=>4
    };
    
    // 同步 send 执行完,readyState 为 4
    xhr.send();
    
打赏作者
您的打赏是我前进的动力
微信
支付宝
评论

中午好👏🏻,我是 ✍🏻   疯狂 codding 中...

粽子

这有关于前端开发的技术文档和你分享。

相信你可以在这里找到对你有用的知识和教程。

了解更多

目录

  1. 1. 发送 AJAX 请求
  2. 2. XHR 的属性
  3. 3. XHR 的方法
  4. 4. XHR 的事件
  5. 5. HTTP 请求
  6. 6. HTTP 状态码 xhr.status
  7. 7. Content-Type 详解
    1. 7.1. Content-Type 格式
    2. 7.2. 常见 Content-Type
  8. 8. 面试题
    1. 8.1. 倒计时抢购
    2. 8.2. readyState 变化几次