XMLHttpRequest基本使用

介绍

原生JS中请求服务器数据所需XHR详解,虽然用不到但是要足够了解!!!

基于XHR发起GET请求

不带参数

// 1. 创建 XHR 对象
var xhr = new XMLHttpRequest()
// 2. 调用 open 函数
xhr.open('GET', 'http://ajax-api.itheima.net/api/books')
// 3. 调用 send 函数
xhr.send()
// 4. 监听 onreadystatechange 事件
xhr.onreadystatechange = function () {
  if (xhr.readyState === 4 && xhr.status === 200) {
    // 获取服务器响应的数据
    console.log(xhr.responseText)
  }
}

在上面状态监听事件中可能会有些迷惑,readyState是什么?status又是什么?
readyState:
在这里插入图片描述

status:
在请求完成前,status 的值为 0。 值得注意的是,如果 XMLHttpRequest 出错,浏览器返回的 status 也为 0。
status 码是标准的 HTTP status codes。举个例子,status 200 代表一个成功的请求。如果服务器响应中没有明确指定 status 码,XMLHttpRequest.status 将会默认为 200。

/**
 * 输出如下:
 *
 * UNSENT(未发送)0
 * OPENED(已打开)0
 * LOADING(载入中)200
 * DONE(完成)200
 */

带参数

var xhr = new XMLHttpRequest()
xhr.open('GET', 'http://ajax-api.itheima.net/api/books?id=1')
xhr.send()
xhr.onreadystatechange = function () {
  if (xhr.readyState === 4 && xhr.status === 200) {
    console.log(xhr.responseText)
  }
}

在上图可以看到我们请求的url地址后面跟了?... 我们把它叫做查询字符串

什么是查询字符串

定义:查询字符串(URL参数)是指在URL的末尾加上用于向服务器发送信息的字符串(变量)。

格式:将英文的?放在URL的末尾,然后再加上参数 = 值,想加上多个参数的话,使用&符号进行分隔。以这个形式,可以将向要发送给服务器的数据添加到URL中。

GET请求携带参数的本质

无论使用$.ajax 还是 $.get亦或者JS原生XHR方法请求数据其实本质上都是将查询字符串追加到url后面实现的。

$.get('url?name=小美&age=18', () => {});
// 等价 ↓↑
$.get('url', {name: "小美", age: 18}, () => {});


$.ajax({
  method: "GET",
  url: "url?name=小美&age=18",
  success: () => {}
});
// 等价 ↓↑
$.ajax({
  method: "GET",
  url: "url",
  data: {name: "小美", age: 18},
  success: () => {}
});

URL编码与解码

什么是URL编码

URL地址中,只允许出现英文相关的字母、标点符号、数字,因此,在URL地址中不允许出现中文字符。

通俗理解:使用英文符号表示非英文符号。

    $.get('url?name=小美&age=18', () => {});
    // 经过url编码后 ↓
    $.get('url?name=%E5%B0%8F%E7%BE%8E&age=18', () => {});

在这里插入图片描述
每个汉字经过编码后分别对应三个%组成的英文字符串

如何进行URI编码与解码

encodeURI() 编码
decodeURI() 解码

const str = '码农张先生'
const str2 = encodeURI(str)
console.log(str2)

console.log('----------')
const str3 = decodeURI('%E5%BC%A0%E5%85%88%E7%94%9F')
console.log(str3)

URL编码的注意事项

由于浏览器会自动对URL地址进行编码操作,因此,大多数情况下,程序员不需要关心URL地址的编码与解码操作。

基于XHR发起POST请求

// 1. 创建 xhr 对象
var xhr = new XMLHttpRequest()
// 2. 调用 open 函数
xhr.open('POST', 'http://www.liulongbin.top:3006/api/addbook')
// 3. 设置 Content-Type 属性 (请求头部)
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
// 4. 调用 send 函数, 同时将数据以字符串的形式提交给服务器
xhr.send('bookname=水浒传&author=施耐庵&publisher=上海图书出版社')
// 5. 监听事件
xhr.onreadystatechange = function () {
  if (xhr.readyState === 4 && xhr.status === 200) {
    console.log(xhr.responseText)
  }
}

POST请求方式且没有使用FormData对象管理表单数据时必须要在open之后send之前设置Content-Type
不知道FormData做什么用?请继续往下看

XHR Level2新特性

设置Http请求时限

实例属性和方法:

XMLHttpRequest
			.timeout = 3000;	// 请求超时时间,单位ms
			.ontimeout(() => {});	// 超时后回调函数

案例演示:

var xhr = new XMLHttpRequest()

// 设置 超时时间
xhr.timeout = 30
// 设置超时以后的处理函数
xhr.ontimeout = function () {
  console.log('请求超时了!')
}

xhr.open('GET', 'http://ajax-api.itheima.net/api/books')
xhr.send()

xhr.onreadystatechange = function () {
  if (xhr.readyState === 4 && xhr.status === 200) {
    console.log(xhr.responseText)
  }
}

FormData辅助上传数据

Ajax操作往往用来提交表单数据。为了方便表单处理,HTML5新增了一个FormData对象,可以模拟表单操作:
使用FormData不需要手动设置Content-Type属性

// 1. 通过 DOM 操作,获取到 form 表单元素
var form = document.querySelector('#form1')

form.addEventListener('submit', function (e) {
  // 阻止表单的默认提交行为
  e.preventDefault()

  // 创建 FormData,快速获取到 form 表单中的数据
  var fd = new FormData(form)

  var xhr = new XMLHttpRequest()
  xhr.open('POST', 'http://ajax-api.itheima.net/api/data')
  xhr.send(fd)

  xhr.onreadystatechange = function () {
    if (xhr.readyState === 4 && xhr.status === 200) {
      console.log(JSON.parse(xhr.responseText))
    }
  }
})

FormData可以在new时传入form表单用作初始值或最终要提交的数据,同时也提供了更多方法,例如append()delete()has()get()getAll()keys()values()等等
参考:MDN | FormData - Web API 接口参考

FormData辅助上传文件

稍微有点长,整个流程

<!-- 1. 文件选择框 -->
<input type="file" id="file1" />
<!-- 2. 上传文件的按钮 -->
<button id="btnUpload">上传文件</button>
<br />
<!-- 3. img 标签,来显示上传成功以后的图片 -->
<img src="" alt="" id="img" width="800" />

<script>
  // 1. 获取到文件上传按钮
  var btnUpload = document.querySelector('#btnUpload')
  // 2. 为按钮绑定单击事件处理函数
  btnUpload.addEventListener('click', function () {
    // 3. 获取到用户选择的文件列表
    var files = document.querySelector('#file1').files

    // 这里files是一个伪数组,正常情况下files[0]是上传文件的信息,它还有另外一个属性length
    if (files.length <= 0) {
      return alert('请选择要上传的文件!')
    }
    var fd = new FormData()
    // 将用户选择的文件,添加到 FormData 中
    fd.append('avatar', files[0])

    var xhr = new XMLHttpRequest()
    xhr.open('POST', 'http://ajax-api.itheima.net/api/file')
    xhr.send(fd)


    // readyState值改变时调用(执行xhr.abort()后不执行)
    xhr.onreadystatechange = function () {
      if (xhr.readyState === 4 && xhr.status === 200) {
        /* xhr.responseText返回一个json字符串 */
        var data = JSON.parse(xhr.responseText)


        /* 注意:这里data是服务器那边处理成功响应的数据,具体应根据响应数据来写,
        下面代码基本可以忽视,因为当前代码块讲的是如何配合FormData上传文件
         */
        if (data.status === 200) {
          // 上传成功
          document.querySelector('#img').src = 'http://ajax-api.itheima.net' + data.url
        } else {
          // 上传失败
          console.log('图片上传失败!' + data.message)
        }
      }
    }
  })
</script>

计算文件上传进度

XMLHttpRequest.upload 属性返回一个 XMLHttpRequestUpload (en-US)对象,用来表示上传的进度。这个对象是不透明的,但是作为一个XMLHttpRequestEventTarget,可以通过对其绑定事件来追踪它的进度。

// 监听文件上传的进度
xhr.upload.onprogress = function (e) {
  if (e.lengthComputable) {
    // 计算出上传的进度
    var procentComplete = Math.ceil((e.loaded / e.total) * 100)
    console.log(procentComplete)
    // 动态设置进度条
    $('#percent').css({"width": procentComplete + "%"}).text(procentComplete + '%')
  }
}

// 获取成功后
xhr.upload.onload = function () {
  $('#percent').removeClass().addClass('progress-bar progress-bar-success')
}

参考文献:MDN | XMLHttpRequest.upload -Web API

END


  • 23
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值