2025-03-29 14:35:49 +08:00

9.1 KiB
Raw Blame History

ajax

XMLHttpRequest(简称 XHR)的发明是为了解决早期 Web 开发中的一个关键问题:如何在不刷新整个页面的情况下,与服务器进行异步通信

xhr

get

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>

  <body>
    <form method="post" action="#">
      姓名: <input type="text" id="name" name="name" /> <span id="msg"></span><br />
      年龄: <input type="number" id="age" name="age" /><br />
      <!-- type="submit"submit有默认的提交行为现在用一用而已以后避免使用它 -->
      <input type="submit" value="注册" />
    </form>
    <script>
      document.querySelector('#name').onchange = function () {
        let name = this.value

        //向后台请求数据, 局部刷新
        //1.创建异步对象
        let xhr = new XMLHttpRequest()

        //2.确定请求地址和请求参数
        xhr.open('get', 'http://127.0.0.1:3002/validataUserName?name=' + name)

        //3.通过send方法可以发起请求, send(string)string仅用于 POST 请求
        xhr.send(null)
        //这个时候在浏览器的response里已经可以看到数据返回, 只是没有接收处理

        // 4.异步对象接收数据
        xhr.onload = function () {
          // console.log(this) 数据在response方法里面, 是字符串格式,再转成对象, 用键的方法取提示
          document.querySelector('#msg').innerHTML = JSON.parse(this.response).msg
        }
      }
    </script>
  </body>
</html>

post

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <form method="post" action="#" enctype="application/x-www-form-urlencoded">
        姓名: <input type="text" name="username" id="username"><br>
        密码: <input type="password" name="password" id="password"><br>
        phone: <input type="number" name="phone" id="phone"><br>
        <input type="button" id="button" value="注册"></input><span id="msg"></span>
    </form>
    <script>
        //大量的数据, 比如图片的传递, 不是通过url, 而是在xhr.send('post', 数据)
        //发送的也是键值对
        //post方式的请求, 有参数的时候就必须设置请求头, 进行编码格式的处理, 否则参数传递了, 服务器也无法获取
        //get方式的请求,不需要设置请求头, 默认utf-8
        //xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
        //form表单里面有参数enctype="application/x-www-form-urlencoded"
        // button 写在form 没有指定类型, 默认是submit, 会默认提交表单刷新页面
        //写成<button type="button"><button/>或者改成<input type="button" /> 或者a标签
        //preservel log, 保留请求日志,跳转页面的时候勾选上,可以看到跳转前的请求


        document.querySelector('#button').onclick = function () {
            let username = document.querySelector('#username').value
            let password = document.getElementById('password').value
            let phone = document.getElementById('phone').value
            console.log(username, password, phone)

            // 1.创建异步对象
            let xhr = new XMLHttpRequest

            //2.1 设置请求行: 请求方式 请求路径  get把键值对拼接到路径后面, post设置请求体
            xhr.open('post', 'http://127.0.0.1:3002/doRegister')

            //2.2 设置请求头, get不需要设置, post定义网络文件的类型和编码
            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
            //application/x-www-form-urlencoded: <form encType=””>中默认的encType

            //2.3 设置请求体: get内容为null, post内容为键值对
            xhr.send(`username=${username}&password=${password}&phone=${phone}`)

            xhr.onload = function () {
                document.querySelector('#msg').innerHTML = JSON.parse(this.response).msg
                console.log(JSON.parse(this.response))
            }
        }
    </script>
</body>

</html>

ajax

封装 ajax

let $ = {
  //option.type 请求类型
  //option.url 请求地址
  //option.data 请求体
  //option.dataType 响应数据类型
  //option.success 处理函数

  /*
        优化: 1. 传入的参数可以是键值对, 也可以是对象, 自动转成键值对
              2. 响应的数据可以是json, 也可以是xml, 默认是对象
     */

  //封装一个把对象转成键值对的方法
  getParams: function (data) {
    if (data) {
      //如果是对象, 转成键值对
      if (typeof data == 'object') {
        let str = ''
        //遍历对象, 拼接
        for (let key in data) {
          str += key + '=' + data[key] + '&'
        }
        //去掉最后多余的&
        return str.substr(0, str.length - 1)
      } else {
        //如果是字符串, 直接返回
        return data
      }
    } else {
      //如果没有传递参数, 返回字符串
      return ''
    }
  },

  //es6新的语法糖
  ajax(option) {
    let type = option.type || 'get'
    let url = option.url

    // console.log(this)
    let data = this.getParams(option.data)

    let dataType = option.dataType || 'text/html'
    let success = option.success

    //1. 初始化异步对象
    let xhr = new XMLHttpRequest()

    //2.1 请求行
    //当为get的时候, 请求行拼接url, 请求体为null
    if (type.toLowerCase() == 'get') {
      url += `?${data}`
      data = null
    }
    xhr.open(type, url)

    //2.2设置请求头
    if (type.toLowerCase() == 'post') {
      xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
    }

    //2.3设置请求体
    xhr.send(data)

    //3.处理函数
    xhr.onload = function () {
      //3.1 判断用户需要的格式, 接收事件请求响应并转化
      let res = null
      if (dataType.toLowerCase() == 'json') {
        res = JSON.parse(this.response)
      } else if (dataType.toLowerCase() == 'xml') {
        res = this.responseXML
      } else {
        res = this.response
      }
      //3.2 调用函数
      //逻辑短路, 没有传入函数直接跳过
      success && success(res)
    }
  },
}

使用

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./js/ajax.js"></script>
</head>

<body>
    <form method="post" action="#" enctype="application/x-www-form-urlencoded">
        姓名: <input type="text" name="username" id="username"><br>
        密码: <input type="password" name="password" id="password"><br>
        phone: <input type="number" name="phone" id="phone"><br>
        <input type="button" id="button" value="注册"></input><span id="msg"></span>
    </form>
    <script>
        document.querySelector('#button').onclick = function () {
            let username = document.querySelector('#username').value
            let password = document.getElementById('password').value
            let phone = document.getElementById('phone').value

            $.ajax({
                type: 'post',
                url: 'http://127.0.0.1:3002/doRegister',
                data: {
                    'username': username,
                    'password': password,
                    'phone': phone
                },
                dataType: 'json',
                // success(res) {
                //     document.querySelector('#msg').innerHTML = res.msg
                // }
            })
        }
    </script>
</body>

</html>

formdata 文件上传

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script src="./js/jquery-1.12.4.min.js"></script>
    <style>
      div img {
        height: 100px;
        width: 100px;
        background-color: #eee;
        object-fit: contain;
        /* https://www.jianshu.com/p/a2ce70fa9584 */
      }
    </style>
  </head>

  <body>
    <form action="">
      <input type="file" name="img" id="img" class="myimg" /> <br />
      <div>
        <img src="" alt="" class="myphoto" />
      </div>
      <input type="button" value="单击上传文件" class="btn" />
    </form>

    <script>
      $(function () {
        $('#img').on('change', function () {
          console.log('aa')
          let formdata = new FormData()
          let myfile = $('#img')[0].files[0]
          console.log(myfile)
          formdata.append('img', myfile)
          $.ajax({
            type: 'post',
            url: 'http://127.0.0.1:3002/uploadFile',
            data: formdata,
            dataType: 'json',
            processData: false,
            contentType: false,
            success: function (res) {
              $('.myphoto').attr('src', 'http://127.0.0.1:3002/images/' + res.img)
            },
          })
        })
      })
    </script>
  </body>
</html>