XMLHttpRequest Level2的新功能&&使用jquery简化文件上传

旧版XMLHttpRequest的缺点

1、只支持文本数据的传输,无法用来读取和上传文件

2、传送和接收数据时,没有进度信息,只能提示有没有完成

XMLHttpRequest Level2的新功能

1、可以设置HTTP请求的时限

有时Ajax操作很耗时,而且无法预知要花多少时间,如果网速很慢,用户可能要等很久,新版本的XMLHttpRequest对象增加了 timeout属性,可以设置HTTP请求的时限:

xhr.timeout = 3000

xhr.ontimeout = function(event){

        alert('请求超时!')

}

上面的语句,将最长等待时间设为3000毫秒。过了这个时限,就自动停止HTTP请求。与之配套的还有一个timeout 事件 用来指定回调函数 

2、可以使用FormData对象管理表单数据

Ajax操作往往用来提交表单数据。为了方便表单处理,HTML5新增了一个FormData对象,

可以模拟表单

  // 新建FormData 对象
  let fd = new FormData()
  // 为FormData 添加表单项
  fd.append('uname','吴大友')
  fd.append('upwd','123456')


  //1、创建xhr对象
  let  xhr2 = new XMLHttpRequest()
  //2、调用open函数 指定请求方式和URL地址
  xhr2.open('POST','http://www.liulongbin.top:3006/api/formdata')
  //3、设置Content-Type 属性(固定写法)
  xhr2.setRequestHeader('Content-Type','application/x-www-form-urlencoded')
  //3、调用send函数 发起Ajax 请求 同时将数据以查询字符串的形式 发送给服务器
  // 直接提交form 对象 这与提交网页表单的效果 完全一样
  xhr2.send(fd)
  //4、 监听onreadystatechange 事件
  xhr2.onreadystatechange = function () {
    // 4.1 监听xhr 对象的请求状态 readyState 和服务器的相应状态 status 固定写法 这里的status 和 res 返回的不是同一个
    if (xhr2.readyState === 4 && xhr2.status === 200){
      // 4.2 打印服务器相应回来的数据 responseText
      let  res = JSON.parse(xhr2.responseText)
      //JSON.parse() 将JSON字符 转换成 对象数据
      console.log(res)
    }
  }

也可以用来获取网页表单的值 

// 获取表单元素
let form1 = document.querySelector('#form1')
// 监听表单的submit事件
form1.addEventListener('submit',function (e) {
  e.preventDefault()
// 根据form 表单创建 FormData 对象,会自动将表单数据填充到FormData 对象种
  let fd1 = new FormData(form1)

// xhr 剩下步骤
 let xhr3 = new XMLHttpRequest()
  xhr3.open('POST','http://www.liulongbin.top:3006/api/formdata')
  //3、设置Content-Type 属性(固定写法)  
  xhr3.setRequestHeader('Content-Type','application/x-www-form-urlencoded')
  //3、调用send函数 发起Ajax 请求 同时将数据以查询字符串的形式 发送给服务器
  // 直接提交form 对象 这与提交网页表单的效果 完全一样
  xhr3.send(fd1)
  //4、 监听onreadystatechange 事件
  xhr3.onreadystatechange = function () {
    // 4.1 监听xhr 对象的请求状态 readyState 和服务器的相应状态 status 固定写法 这里的status 和 res 返回的不是同一个
    if (xhr3.readyState === 4 && xhr3.status === 200){
      // 4.2 打印服务器相应回来的数据 responseText
      let  res = JSON.parse(xhr3.responseText)
      //JSON.parse() 将JSON字符 转换成 对象数据
      console.log(res)
    }
  }
})

3、可以上传文件 并且 获得数据传输的进度信息

实现步骤:

  1. 定义UI结构
  2. 验证是否选择了文件
  3. 向FormData中追加文件
  4. 使用xhr发起上传文件的请求- xhr.upload.onprogress 事件计算返回进度的百分比,运用合适的组件库渲染到页面上(这里用的是bootstrap)
  5. 监听onreadystatechange事件-完成后移除上传过程与用的样式,添加上传完成时用的样式

UI结构

选择按钮和提交按钮
<div>
  <input type="file" id="file1" value="选择图片">
  <button id="btn">上传图片</button>
</div>

进度条显示区域
<div class="progress" style="width: 500px;display: none">
  <div class="progress-bar progress-bar-striped active"  style="width: 0%" id="plan">
  </div>
</div>

图片展示区域 上传完成后为此元素增加 src 属性
<img src="" alt="" id="img" width="800" style="display: block">

script:

  let btn = document.querySelector('button')
  btn.addEventListener('click',function () {
      let files = document.querySelector('#file1').files
      if (files.length <= 0){
        alert('没有选择文件、请重新选择')
        return
      }
     $('.progress').css('display','block')
      let fd = new FormData()
      fd.append('avatar',files[0])
      let xhr = new XMLHttpRequest()

    // 监听 xhr.upload 的 onprogress 事件
    xhr.upload.onprogress = function(e){
      // e.lengthComputable 是一个布尔值 表示当前上传的资源是否具有可计算的长度
      if (e.lengthComputable){
        // e.loaded 已经传输的字节  e.total  需要传输的总字节
        let schedule = Math.ceil((e.loaded / e.total) * 100)
        // 赋值更新进度条的宽度和百分比
        $('#plan').attr('style','width:'+schedule+'%').html(schedule+'%')
      }
    }

      xhr.upload.onload = function(){
        $('#plan').removeClass().addClass('progress-bar progress-bar-success')
        setTimeout(function () {
          $('.progress').css('display','none')
        },250)
      }


      xhr.open('POST','http://www.liulongbin.top:3006/api/upload/avatar')
      xhr.send(fd)
      xhr.onreadystatechange = function () {
          if (xhr.readyState === 4 && xhr.status === 200){
            let data = JSON.parse(xhr.responseText)
            if (data.status === 200){ // 内部再判断一下 因为和外面的 status 不是同一个
              // 将置留的img 加上src
              let img = document.querySelector('#img')
              img.src = 'http://www.liulongbin.top:3006'+data.url
            }else {
              console.log(data.message)
            }
          }
      }
  })

依赖的资源:

 <script src="http://www.wsg3096.com/ass/jquery-3.6.0.js"></script>

  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">

  <script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js" integrity="sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd" crossorigin="anonymous"></script>

使用jquery简化文件上传 

jquery使用Ajax上传文件时 

只需要添加配置

        // 不修改content-Type 属性 使用FormData 默认的Content-Type值

        contentType:false,

        // 不对FormData 中的数据进行url 编码 而是将FormData 原样数据发送到服务器

        processData:false,

并且运用ajaxStart   ajaxStop 两个回调函数 进行等待图片的显示和隐藏操作

  $(document).ajaxStart(function () {

    $('#load').fadeIn()

  })

  $(document).ajaxStop(function () {

    $('#load').fadeOut()

  })

 

完成代码: 

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>17jQuery简化文件上传</title>
  <script src="http://www.wsg3096.com/ass/jquery-3.6.0.js"></script>
  <style>
    #load{
      position: absolute;
      transform: translate(-50%,-50%);
    }
  </style>
</head>
<body>
<input type="file" id="file1">
<button>上传</button>
<img src="" alt="" style="display: block" id="wsg">


  <img src="pic/load.gif" alt="" style="max-width: 360px;display: none" id="load">

<img src="pic/jquery-upload.jpg" alt="" style="display: block">
<script>
  $('button').on('click',function () {
    // [0] 转化成dom 对象
    let files = $('#file1')[0].files
    if (files.length<= 0){
      alert('请选择文件后再上传')
      return
    }else {
      let fd = new FormData()
      fd.append('avatar',files[0])
      $.ajax({
        method:'POST',
        url:'http://www.liulongbin.top:3006/api/upload/avatar',
        data:fd,
        // 不修改content-Type 属性 使用FormData 默认的Content-Type值
        contentType:false,
        // 不对FormData 中的数据进行url 编码 而是将FormData 原样数据发送到服务器
        processData:false,
        success:function (res) {
          console.log(res)
          let url = 'http://www.liulongbin.top:3006'+res.url
          $('#wsg').prop('src',url)
        }
      })
    }
  })
  
  $(document).ajaxStart(function () {
    $('#load').fadeIn()
  })

  $(document).ajaxStop(function () {
    $('#load').fadeOut()
  })
</script>

</body>
</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值