JS 中的ajax

220 阅读6分钟

前后端交互

其实就是一个前后端通讯,是我们在开发中,必不可少的一个技能
目前我们用到的技术是 ajax
流程为 在前端开发中,在某一个时刻(页面首次打开渲染的时候,或者点击下一页需要新的数据的时候),此时通过 ajax 向后端(服务器)发送一个请求,拿到 所谓的数据

实现一个 ajax 请求

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

2.配置 ajax 对象(三个参数)
xhr.open('GET','http://localhost:8888/test/first', true)

3.发送请求
xhr.send()

4.配置接收响应函数
xhr.onload = function(){
    console.log(xhr.responseText)
}

ajax 的异步问题

ajax 是否异步为 第二步配置的第三个参数决定的, 也就是那个布尔值
    默认是 true 代表的是开启异步,如果传递的是 false 代表关闭异步开启同步
同步和异步的差别:
    1.创建一个 ajax 对象   (同步代码)
    2.配置请求             (同步代码,但是第三个参数决定了  下一步是否为异步)
    3.发送请求
    4.接收响应             (同步代码)
    
    => 如果传递的是 true 或者 没有传递,那么为异步,此时的流程为
            1.创建一个对象
            2.配置对象
            3.发送请求
            4.接收xiangying
            5.响应完成
    
    =>如果传递的是 false,那么为同步,此时的运行流程
            1.创建一个对象
            2.配置对象
            3.发行一个请求,等待请求完成后,开始执行后边的代码
            4.接收响应(前边三步已经把这个请求完全的运行结束了,所以此时不可能再触发这个函数了)
    => 如果传递的是 false, 那么为同步,此时的运行流程
            1.创建一个对象
            2.配置对象
            4.接收响应,等到请求完成的时候, 会触发
            3.发送一个请求,等待请求完成后,开始执行后边的代码
    
    如果传递的是异步 ,可以按照 1234的流程书写(1243也可以)
    果传递的是同步, 必须按照 1243 的流程书写,所以在开发的时候, 为了方便起见, 一般都会书写了  1243
    1243:
        // 1.创建一个 ajax  对象
        const xhr = new XMLHttpRequest()

        // 2.配置 ajax  对象
        xhr.open('GET','http://localhost:8888/test/first',false)

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

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

http传输协议

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

ajax 的状态码

通过一个数字,表明 ajax 当前运行到哪一步了
获取状态码
    语法: 对象名.readyState
    
    0.ajax 创建成功
    1.当前 ajax 配置成功
    2.当前 ajax 发送成功
    3.当前 浏览器 正在解析服务端返回给我们的内容,如果返回的内容少,这一步基本能接收完;
        如果返回的内容很多这一步是接收的不完整的
    4.表明  浏览器  已经把服务端返回的内容,全部解析完毕了~
    例:
        1.创建一个 ajax 对象
        const xhr = new XMLHttpRequest()
        console.log(xhr.readyState)  //0
        
        2.配置对象
        xhr.open('GET','http://localhost:8888/test/first',true)
        console.log(xhr.readyState) //1
        
        4.配置接收响应式函数
        xhr.onload = function () {
            console.log(xhr.responseText)
        }
        
        3.发送请求
        she.send()
        xhr.onreadystatechange = () =>{
            if (xhr.readyState === 4) {
                console.log('当前浏览器已经完全解析完毕  返回的数据', xhr.responseText)
            }
        }

请求方式的区别

get  偏向于获取的语义   (商品列表数据, 用户详情,商品详情)
    delete 偏向于获取的语义 (删除某一个内容)
post  偏向于修改的语义  (修改用户名,修改密码)
    put     偏向于修改的语义 (修改库存,修改收藏数量)  等等......
    
现在 日常中常用的方式只有两个  get/post
请求方式不同,会导致传参的方式不同,除此之外我们前端来说没有区别
      => get: 直接将需要传递参数拼接在路径后即可,注意使用 ? 间隔
          例:`http://localhost:8888/test/first?key=value`
          
      => post: 也是需要传递字符串,只不过不再放在 地址路径后,而是放在 请求体内书写(其实就是  xhr.send())
             在传参的时候还需要配置一个请求头中的属性 content-type
             content-type 赋值的时候,还要区分我们传递的是普通字符串,还是 json 格式的字符串
例1:
    1.创建一个对象
    const xhr = new XMLHttpRequest()
    
    2.配置对象
    xhr.open('GERT','http://localhost:8888/test/second?name='彭于晏'&age=41')
    
    4.接收响应式函数
    xhr.onload = () => {
        const res = JSON.parse(xhr.responseTest)
        console.log(res)
    }
    
    3.发送请求
    xhr.send()
    
例2:
    1.创建一个对象
    const xhr = new XMLHttpRequest()
    
    2.配置对象
    xhr.open('POST','http://localhost:8888/test/fourth')
    
    4.配置响应式函数
    xhr.onload = () => {
        const res = JSON.parse(xhr.responseTest)
        console.log(res)
    }
    
    3.1 post 请求传参时需要配置  content-type
    xhr.setRequestHeader('content-type','application/x-www-form-urlencoded')
    
    3.发送请求
    xhr,send('name='秦霄贤'&age=24')
    

封装 ajax

封装 ajax 为什么要用 promise?
    因为在配置 ajax 对象中的第三个参数会决定ajax是不是异步代码,封装异步代码有两种方法(回调函数和 prmise)。
问题:如果封装,需要处理些什么?比如参数需要些什么?
参数:
    1.请求的方式: 选填,默认值为 GET; 形参名: type
    2.请求的地址:必填; 形参名: url
    3.请求为同步还是异步: 选填,默认值为 true; 形参名: async
    4.请求需要携带的参数:选填,默认值为空字符串''
返回值:
    需要返回一个 promise 对象,后续可以通过 .then 或者 async/await 去使用
    
fucntion myAjax (options){
      1.验证 参数中的 url (必传项)
      if(options.url === undefined)  throw new Error('参数中缺少比传项 url')
      
      1.1参数格式验证(type 只接受 undefined 或者 string 两种类型)
      if(!(options.type === undefined || typeof(options.type) === 'string')){
          throw new Error('参数中的 type 值的类型必须为 string')
      }
      
      2.封装默认值
      const _options = {
          url: options.url,
          type: options.type || 'GET',
          data: options.data || '',
          //控制检测符, 该符号的特点 只会在 左侧的值为空值的时候返回右侧, 比如左侧为  null, undefined
          async:options.async ?? true
      }
      // 3.如果当前_options.data 有值, 并且 _options.type 是 GET 方式,我们直接将 data 拼接到 url 后边
      if(_options.data && /^()GET&/i.test(_options.type)){
          _options.url += '?' + _options.data
      }
      
      // 封装异步(ajax请求)代码  (封装异步代码有两种方法:回调函数和promise,常用promise)
      const p = new Promise ((res,rej) => {
            const xhr = new XMLHttpRequest()
            xhr.open(_options.type, _options.url, _options.async)
            xhr.onload = function () {
                  res(JSON.parse(xhr.responseText))
            }
            if (/^(POST)$/i.test(_options.type)){
                  xhr.setRequestHeader('content-type','application/x-www-form-urlencoded')
                  xhr.send(_options.data)
            } else{
                  xhr.send()
            }
    
          })
          return p
        }
        }
        myAjax()