Ajax

64 阅读7分钟

Ajax

什么是Ajax

其实就是一个实现前后端通信必不可少的一个方法, 通过向服务端发送请求获取选相关数据,然后重新渲染在页面上,这种渲染只需要渲染局部返回,不会影响整个页面.

Ajax的实现流程

流程为: 在前端开发中,在某一时刻(页面首席打开渲染或者页面更新数据时), 此时通过 Ajax 向后端(服务器)发送一个请求能拿到 数据发送请求需要传一些参数(就是告诉后端你需要什么),如果不知道,可以看与项目有关的 '接口文档'

下面,我们通过代码实现一个简单的Ajax请求

请牢记下述代码的顺序,后续讲解中我们需要继续使用这个顺序

    //1.创建一个Ajax对象
    const xhr = new XMLHttpRequest()

    //2.配置Ajax 对象
    // xhr.open('请求的方式(不区分大小写)', '请求的地址', '一个布尔值') 
    xhr.open('GET', 'http://localhost:8888/test/second', true) 

   
    //3. 发送请求
    xhr.send()

    //4. 接收响应
    xhr.onload = function(){
      console.log(xhr.responseText)
    }

注意在上述代码中,我们给的布尔值是true,只是同步代码,而改成false时,就会变为异步代码,继续采用上述代码顺序的话,我们就无法从服务端获取相关数据,接下来我们来看一下Ajax同步和异步的区别以及代码书写有什么不同

Ajax的异步问题

ajax是否异步是第二步配置的第三个参数决定的,也就是那个布尔值

默认为true 代表的是开启异步,如果传选的是false代表关闭异步开启同步

同步和异步的差别

 *    1. 创建一个ajax对象(同步代码)
 *    2. 配詈对象(同步代码,但是第三个参数次定了下一步是否为异步)
 *    3. 发送请求(根据上一步的配置,才能看出是否为异步)
 *    4. 接受啊应(同步代码)
 

同步代码

如果传递的是true或者没有传递,那么为 异步 ,此时的运行流程

 *    1.创建一个对象
 *    2.配置置对象
 *    3.发送请求
 *    4.接收响应
 *    5.啊应完成了
 

异步代码

如果传递的是false,那么为 同步 ,此时的运行流程为

 *    1.创建一个对象
 *    2.配置对象
 *    3.发送一个请求,等待请求完成后,执行后面代码
 *    4.接收响应(前面三步已经把这个请求完全运行结束了,所以不可能再触发这个函数了)

解决方法:

我们只需对代码的顺序进行一个调整就可以了

 1.创建一个对象
 2.配置对象
 4.接收响应,等待请求完成时候,会触发
 3.发送一个请求,等待请求完成后,执行后面代码
 

我们来看一下调整后的代码

    //1.创建一个Ajax对象
    const xhr = new XMLHttpRequest()
    
    //2.配置Ajax 对象
    xhr.open('GET', 'http://localhost:8888/test/second', false) 

    //4. 接收响应
    xhr.onload = function(){
      console.log(xhr.responseText)
    }

    //3. 发送请求
    xhr.send()

http 传输协议

还有一个协议 https , 相当于http的升级版,相对于http安全一点点
   
根据传输协议规定,必须是前端向后端发送,发送请求的时候如果携带一些参数,必须是字符串格式
   
1.建立连接
        浏览器和服务器端 建立一个连接
2.发送请求
        要求前端必须以 '请求报文' 的形式发送;
        请求报文由浏览器进行纽装,我们只需要是供对应的信息即可;
        比如说:请求的方式,请求的地址,请求需要的参数
3.接收响应
        要求后端必须以 '请求报文' 的形式返回;
        响应报文内有一个东西叫做响应状态码;
4.断开连接
        浏览器和服务端的连接断开
   
响应状态码:
        100~199   表明连接还在继续
        200~299   表明连接各种成功;  但是现在普遍只返回一个200
        300~399   表明请求重定向
        400~499   表明请求失败;   但现在只会看到一些 403  404 400 等;一般4开头是前端问题
        500~599   表明服务端出错, 通常来说可能是后端问题

ajax的状态码

我们可以通过 xhr.readyState来获取

通过获取到的一个数字,表明Ajax 当前运行到那一步了

 0 : Ajax 创建成功
 1 : 当前Ajax 配置成功
 2 : 当前Ajax 发送成功
 3 : 当前 浏览器 正在解析服务端发给我们的内容
         如果返回的内容少,这一步基本能接收完
         如果内容多这一步是接收不完整的
 4 : 表明 浏览器 已经把服务端返回的内容 完全解析完毕了
 

我们来结合代码看一下


    //1.创建一个Ajax对象
    const xhr = new XMLHttpRequest()
    //console.log(xhr.readyState) // 0

    //2.配置Ajax 对象 
    xhr.open('GET', 'http://localhost:8888/test/second', true)
    //console.log(xhr.readyState)  //1

    // 4. 接收响应
   // xhr.onload = function () {
      //console.log(xhr.readyState)//1
   //   console.log(xhr.responseText)
    //}

    //3. 发送请求
    xhr.send()
    //console.log(xhr.readyState)//4

        //我们将第4步换一种方式书写,当**状态码**发生变化时,会触发 `onreadystatechange` 事件发生
    xhr.onreadystatechange = function () {
         if (xhr.readyState === 4) {
         console.log('当前浏览器已经完全解析完毕', xhr.responseText)
       }
    }

Ajax的请求方式及其不同

Ajax 去请求方式有好几种,但是目前我们最常用的就是 getpost , 虽然是不同请求方式,也仅仅只是传参的方式不同,其他方面时没有区别.

get

语义偏向获取获取; 例如获取商品列表,用户详情等

与其语义相似的比如 delete 是指删除某一个内容

get 传参的方式

get : 直接将需要传递的参数以字符串的形式拼接在路径的后面,用 key=value 的形式, 注意用 ? 与路径间隔开

例如: http://localhost:xxx/test/second?key=value

    const xhr = new XMLHttpRequest()
    xhr.open('GET', 'http://localhost:8888/test/third?name=zhangsan&age=18', true)
    xhr.onload = function () {
      const res = JSON.parse(xhr.responseText)
      console.log(res)
    }
    xhr.send()

post

post : 也是传递字符串,只是不放在路径后,而是放在请求体内书写

xhr.send('需要传递的参数')

在传参时候还需要匹配一个请求头中的属性 content-type

content-type在赋值的时候,还要区分我们传递的是普通字符串还是json格式的字符串

设置请求头:

普通字符串:

xhr.setRequestHeader('content-type','application/x-www-form-urlencoded')

json字符串:

xhr.setRequestHeader('content-type','application/json')

    //1.创建一个Ajax对象
    const xhr = new XMLHttpRequest()
    
    //2.配置Ajax 对象
    xhr.open('post', 'http://localhost:8888/test/fourth', true)
    
    //4.接收响应
    xhr.onload = function () {
      const res = JSON.parse(xhr.responseText)
      console.log(res)
    }
    //3.1 post传参时,设置请求头 ,配置 content-type
    xhr.setRequestHeader('content-type','application/x-www-form-urlencoded')
    //3.2发送请求
    xhr.send('name=张三&age=18')

Ajax 的封装

 参数:
     1.请求的方式: 选填,默认是get;  形参名: type
     2.请求的地址: 必填,   形参名: url
     3.请求为同步还是异步   选填, 默认true  形参名: async
     4.请求需要的参数: 选填,默认 '' (空字符串)  形参名 : data
  
返回值: 
      需要返回一个 promise 对象,后续可以通过 .then 或者async/await 去使用
      
    function Ajax(options) {
      //1.验证参数中的url
      if (options.url === undefined) {
        //返回错误
        throw new Error('代码中缺少url'); 
      }

      //1.1 参数格式验证,拿请求方式举例: type 只接收 undefined 或者 string 两种类型
      if (!(options.type === undefined || typeof(options.type))) {
        throw new Error('参数type的值的类型仅支持string');
      }

      //2.封装默认值
      const _options = {
        url: options.url,
        type: options.type || 'get',
        data: options.data || '',
        //空值检测符  ??  该符号特点.只会在左侧的值为空值时返回右侧
        async: options.async ?? true
      }

      const xhr = new XMLHttpRequest()
      xhr.open(_options.type,_options.url,_options.async)
      xhr.onload = function(){
        console.log(xhr.responseText)
      }
      xhr.send()

      
      console.log('如果代码执行到这个位置,可以发送请求了~-~w ')
    }
    Ajax({
      url: 'http://localhost:8888/test/second',
    })