XMLHttpRequest的基本用法

XMLHttpRequest的基本用法

什么是XMLHttpRequest

  1. 是一个浏览器内置的构造函数

  2. 它的作用:基于 new 出来的 XMLHttpRequest 实例对象,可以发起 Ajax 的请求。 axios 中的 axios.get()、axios.post()、axios() 方法,都是基于 XMLHttpRequest(简称:XHR) 封装出来的!

    使用XMLHttpRequest发起get请求

    通过4个主要的步骤来实现

    1. 创建 xhr 对象

    2. 调用 xhr.open() 函数

    3. 调用 xhr.send() 函数

    4. 监听 load 事件

image.png load事件也可以放到前面

image.png

用原生的方式发起get请求:

  ```html
  <!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>
  </head>
  
  <body>
      <button>获取所有图书资源</button>
      <script>
          let btn = document.querySelector('button')
          btn.addEventListener('click', function () {
              // 1.创建异步对象
              let xhr = new XMLHttpRequest()
  
              // 2.使用异步对象发起请求
              // 2.1 请求行
              xhr.open('get', 'http://www.itcbc.com:3006/api/getbooks?id=12163')
              // 2.2 请求头:get不用设置请求头
              // 2.3 请求体:get方式的参数在url中拼接了。所以不用单独的传递请求体
              // 如果在请求体中单独传递参数,相当于没有传递
              xhr.send()
  
              // 3.接受响应
              xhr.addEventListener('load', function () {
                  console.log(JSON.parse(xhr.response));
              })
          })
      </script>
  </body>
  
  </html>
  ```

  

image.png

JSON的语法规范:

image.png

原生方式发起post请求:

<!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>
</head>

<body>
    <form class="card-body bg-light" id="addForm">
        <!-- 书名 -->
        <div class="input-group mb-3">
            <div class="input-group-prepend">
                <span class="input-group-text">书名</span>
            </div>
            <input type="text" class="form-control" placeholder="请输入图书名称" name="bookname" />
        </div>
        <!-- 作者 -->
        <div class="input-group mb-3">
            <div class="input-group-prepend">
                <span class="input-group-text">作者</span>
            </div>
            <input type="text" class="form-control" placeholder="请输入作者名字" name="author" />
        </div>
        <!-- 出版社 -->
        <div class="input-group mb-3">
            <div class="input-group-prepend">
                <span class="input-group-text">出版社</span>
            </div>
            <input type="text" class="form-control" placeholder="请输入出版社名称" name="publisher" />
        </div>
        <input type="button" value="添加" class="btn btn-dark btnadd" />
    </form>
    <script>
        let btnadd = document.querySelector('.btnadd')
        let bookname = document.querySelector('[name="bookname"]')
        let author = document.querySelector('[name="author"]')
        let publisher = document.querySelector('[name="publisher"]')
        btnadd.addEventListener('click', function () {
            // 获取元素value值
            let booknameV = bookname.value
            let authorV = author.value
            let publisherV = publisher.value
            // 创建异步对象
            let xhr = new XMLHttpRequest()

            // 发起请求
            // 请求行
            xhr.open('post', 'http://www.itcbc.com:3006/api/addbook')
            // 请求头:post方式传递普通键值对,需要设置content-type编码格式
            xhr.setRequestHeader(
                'Content-Type',
                'application/x-www-form-urlencoded'
            )
            // 请求体
            xhr.send(
                `bookname=${booknameV}&author=${authorV}&publisher=${publisherV}`
            )
            // 接受响应
            xhr.addEventListener('load', function () {
                console.log(JSON.parse(xhr.response));
            })
        })
    </script>
</body>

</html>

封装自己的ajax:

// 创建一个函数用于连接参数
function parseObjectToString(obj) {
    let arr = []
    for (let key in obj) {
        arr.push(key + '=' + obj[key])
    }
    // join方法,用于将数组各项连接成为一个字符串
    // 括号内为分隔符
    return arr.join('&')
}

// option.method:请求方式
// option.url:请求地址
// option.params:url参数
// option.data:请求体参数
// success:请求成功之后的回调函数
// 解构对象,对象的各个键值对可以直接获取到值了
function ajax({ method, url, params, data, success }) {
    // 1. 创建异步对象
    let xhr = new XMLHttpRequest()
    // 2. 使用异步对象发起请求
    // 2.1 设置请求行
    // 这是get时请求行的判断和执行的操作   判断有get和params同时存在时
    if (method.toLowerCase() == 'get' && params) {
        // get方式,请求行的url格式为'地址?参数=值&参数=值'
        // 这里调用上面的拼接参数=值的函数来处理params
        url += '?' + parseObjectToString(params)
    }
    xhr.open(method, url)
    // 2.2 设置请求头
    // 2.3 设置请求体
    // instanceof:判断一个构造函数是否是某个构造函数,意味着判断对象是否是某个构造函数创建的
    // 这里判断这个函数是不是由FormData创建的,就是判断它是不是FormData
    if (data instanceof FormData) {
        // 如果是FormData则不需要进行处理
        xhr.send(data)
    }
    // 判断你输入的类型是不是对象,然后根据对象的方式进行转成字符串
    else if (typeof data == 'object') {
        xhr.setRequestHeader('Content-Type', 'application/json')
        xhr.send(JSON.stringify(data))
    }
    // 判断你输入的类型是不是字符串,如果是解码然后直接输出
    else if (typeof data == 'string') {
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
        xhr.send(data)
    }
    // 最后判断你有没有传参,如果没有,直接给你输出
    else {
        xhr.send()
    }

    // 3.使用异步对象接收响应
    xhr.addEventListener('load', function () {
        // 前面都转换为了字符串,为了输出的好看,这里转换为对象的形式
        // success()函数是ajax()向后台请求成功后自动调用的,在success(response)函数里面的变量只有一个,且里面不能调用自定义的变量,response是后台返回来的值。
        success(JSON.parse(xhr.response))
    })
}