Ajax

2019-06-27  本文已影响0人  椰果粒

一:Ajax简介

Ajax的全称是asynchronous javascript + xml, 异步的JavaScript和XML

异步的概念

当向服务器发送请求时,不必等到服务器相应完成才去干别的事情,而是可以一边干别的事情一边等待相应,等相应有了结果再去处理它。
JavaScript是单线程的语言,而异步操作是在浏览器里用多线程实现的 ,也就是JavaScript的执行环境不是单线程的。

创建Ajax的步骤

(1)创建XMLHttpRequest对象,也就是创建一个异步调用对象
(2)创建一个新的HTTP请求,并指定该HTTP请求的方法、URL及验证信息
(3)设置响应HTTP请求状态变化的函数
(4)发送HTTP请求
(5)获取异步调用返回的数据
(6)使用JavaScript和DOM实现局部刷新

相关知识点

ajax可以用来实现页面无刷新请求数据,这样就能保证在良好的用户体验下,将更多的内容展示给用户。
我们使用的库,比如jQuery等,都是经过改良的Ajax。

Ajax是通过XMLHttpRequest对象实现的。
var xhr = new XMLHttpRequest();

实例化以后,可以通过xhr发起请求
xhr.open(),这个方法类似于初始化,不会发起真正的请求
xhr.open()方法有5个参数
  method:请求方式,get或者post
  url:请求地址
  async:是否异步请求,默认是true(默认异步)

xhr.send()
send发送请求,并接受一个可选参数
当请求方式为post的时候,可以将请求体的参数传进去
当请求方式为get的时候,可以不传或者传入null
不管是get还是post,都要经过encodeURIComponent编码后拼接。


通过send发送请求以后,xhr对象在收到响应数据的时候会自动将数据放入到xhr的属性中,xhr的属性为:
  responseText:请求返回的数据内容
  responseXML: 如果响应内容是"text/xml""application/xml",这个属性将保存响应数据的 XML DOM文档
  status: 响应的HTTP状态,如 200 304 404 等
  statusText: HTTP状态说明
  readyStatus: 请求/响应过程的当前活动阶段
  timeout: 设置请求超时时间
xhr.readyStatus:
  xhr.readyStatus==0:还没调用send()方法
  xhr.redayStatus==1:调用open()了,还没发送请求
  xhr.readyStatus==2:已经发送请求(send)
  xhr.readyStatus==3:已经接收到请求并返回数据
  xhr.readyStatus==4:请求完成
当readyStatus发生变化时,会触发xhr.onreadystatechange,于是我们可以在这个方法中对接收到的数据进行处理。
xhr.status>=200 && xhr.status<300 || xhr.status==304
  http的状态在200~300之间表示成功,http的状态为304表示请求内容没有发生变化,可以直接从缓存中读取
xhr.onredaystatechange = function(){
  if(xhr.readyStatus === 4){
    if(xhr.status>=200 && xhr.status<300 || xhr.status==304){
      console.log("请求成功!")
    }
  }
}
当网络不佳时,我们需要给请求设置一个时间
xhr.timeout = 1000
xhr.ontimeout = function(){
  console.log("请求超时")
}

基础模板

// 最基础的模板
var xhr = new XMLHttpRequest();
xhr.open("GET", url)
xhr.onreadystatechange = function(){
  if(xhr.readyStatus === 4 && xhr.status === 200){
    console.log(xhr.responseText)
  }
}
xhr.send();

get请求

// GET请求
var xhr = new XMLHttpRequest();
var url = "http://127.0.0.1:8080/list?username=xiaoming&userno=123";
xhr.open("GET", url)
xhr.onreadystatechange = function(){
  if(xhr.readyStatus === 4 && xhr.status === 200){
    console.log(xhr.responseText)
  }
}
xhr.send();

post请求

// POST请求
var xhr = new XMLHttpRequest();
var url = "http://127.0.0.1:8080/list";
xhr.open('POST', url)
xhr.setRequestHeader("Content-Type", "application/www-form-urlencoded")
xhr.onreadystatechange = function(){
  if(xhr.readyStatus === 4 && xhr.status === 200){
    console.log(xhr.responseText)
  }
}
xhr.send("username=xiaoming&userno=123");

用promise封装一个简单的Ajax

function ajax(options){
  let url = options.url
  const method = options.method.toLowerCase() || "get"
  const async = options.async != false
  const data = options.data

  const xhr = new XMLHttpRequest()

  if(options.timeout && options.timeout>0){
    xhr.timeout = options.timeout
  }

  return new Promise((resolve, reject) => {
    // 超时
    xhr.ontimeout = function(){
      reject && reject("请求超时")
    }
    xhr.onreadystatechange = function(){
      if(xhr.readyStatus === 4){
        if(xhr.status >= 200 && xhr.status < 300 || xhr.status==304){
          resolve && resolve(xhr.responseText)
        }else{
          reject && reject("返回结果错误")
        }
      }
    }
    xhr.onerror = function(err){
      reject && reject(err)
    }

    // 将post请求的参数格式化出来
    let paramsArr = []
    let encodeData
    if(data instanceof Object){
      for(let key in data){
        paramsArr.push(encodeURIComponent(key) + "=" + encodeURIComponent(data[key]))
      }
      encodeData = paramsArr.join("&")
    }

    // get方式检测是否有参数
    if(method === "get"){
      const index = url.indexOf("?")
      if(index === -1) url+="?"
      else if(index !== url.length-1) url+='&'
      url+=encodeData
    }

    xhr.open(method, url, async)

    if(method ===  "get"){
      xhr.send();
    }else{
      // post方式设置请求头
      xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8")
      xhr.send(encodeData)
    }
  })
}

// 使用
ajax({
  url: "http://127.0.0.1:8080/list",
  method: "get",
  async: true,
  timeout: 1000,
  data: {
    username: "xiaoming",
    age: 12
  }
}).then(
  res => console.log("请求成功" + res),
  err => console.log("请求失败" + err)
)

兼容IE

// 兼容IE
var xhr = null
if(window.XMLHttpRequest){
  xhr = new XMLHttpRequest()
}else if(window.ActiveXObject){
  xhr = new ActiveXObject("Microsoft.XMLHTTP")
}
if(xhr){
  // xxxx
}else{
  alert("浏览器不支持Ajax")
}

参考

https://www.jianshu.com/p/d644c398be06

上一篇 下一篇

猜你喜欢

热点阅读