AJAX笔记
何为ajax
全称:Asynchronous JavaScript and XML。
用途: 在不重新加载页面的情况下发送请求给服务器。 接受并使用从服务器发来的数据。
常用概念
XMLHttpRequest
XmlHttpRequest是一个浏览器实现的一个接口,通过它发送一个ajax的请求(发出和接收HTTP请求),实现页面不刷新与服务端交互
var xhr = new XMLHtppRequest()
// 创建XMLHtppRequest 的实例
open( ) 方法
XMLHtppRequest 提供的open( )方法启动请求而不是立马发送,
以下是它的三个参数使用
- Method 请求方法: GETPOSTDELETEHEADOPTIONSPUT,通常大写
- url 请求url: 绝对路径和相对路径
- async 是否异步: 默认是true 表示异步
xhr.open("GET","/name.json")
请求头
在open() 之后设置,send()之前设置,重复设置只会 是添加而不是覆盖
xhr.setRequestHeader("Content-Type","text/plain")
发送请求 send()
发送请求方法可以没参数,特别是对GET请求
xhr.send()
以上是发送请求和数据给服务器
那么如何获得响应呢?
取得响应内容
完整的响应有状态码、响应头、响应主体组成,而XMLHttpRequest有对应的属性来使用,分别如下:
- 
status和statusText分别是响应的状态和状态说明 例如200、OK
- 
getResponseHeader() 和 getAllResponseHeader()查询响应头,后者过滤掉cookie头,前者当接受到"set-cookie"和"set-cookie2"" 返回null 
- 
响应主体 responseText响应主体的文本形式 和responseXML响应主体的DOM XML形式
监听响应状态
前面的属性是在响应完成后取得,如何知道响应完成,就需要为请求加上监听以完成后得到通知,而这个可以通过XMLHttpRequest的 readystatechnge 事件来监听,因为XMLHttpRequest有个readyState ,而这个属性就是在请求和响应过程中的状态,每当这个属性值改变(状态发生改变)就会触发readystatechnge事件。所以在发起请求之前为它定义这个时间则可以完成监听。
var xhr = new XMLHttpRequest()
xhr.open("GET",url,true)
// 定义事件
xhr.onreadystatechange = function () { 
  // 判断是否响应完成
  if(xhr.readyState == 4) {
    // 响应完成后判断是否请求到数据或者 数据没有被修改
    if(xhr.status >= 200 && xhr.status < 300 || xhr.status == 304) {
     // 输出响应的数据文本形式
      console.log(xhr.responseText)
    }
  }
}
解析为什么监听事件放在发送请求之上,对于异步的事件来说,它不会同步被执行,而是进入了”等待执行状况“,由于请求也是异步的,所以本身代码是不会等待他们而是继续执行,事件比请求先进入栈中,所以在数据到来的过程中readyState会变化,而这个又会引发事件的效果,事件检测是否满足条件然后执行响应的回调函数。
提供readystate值:
| 0 | 未初始化 | 尚未调用open() 方法 | 
|---|---|---|
| 1 | 启动 | 已经调用open()方法,但未调用send()方法 | 
| 2 | 发送 | 已经调用send()方法,但尚未接收响应 | 
| 3 | 接收 | 已经接收到部分响应 | 
| 4 | 完成 | 接收到全部响应,可被使用 | 
发送请求xhr.send(data)
data 的数据类型可以有以下几种,在请求类型不是 GET HEAD下生效
FormData ,ArrayBuffer,Blob,Document,DOMString,FormData,null
这些会让XHR对象自动为其设置相应的头部信息,具体参见你真的会使用XMLHttpRequest吗?
进度事件
- 
loadstart 接收到响应数据的第一个字节触发 
- 
progress 在接收响应期间不断被触发 
- 
error 在请求发生错误时触发 
- 
abort 
调用abort() 方法时被触发
- load
接收到完整响应数据时触发
因为load事件是在接收到响应后就会被触发,对于相应的状态不做检查,所以需要加上检查的判断语句,且使用onload始终触发事件对象时xhr对象,所以通用。
   xhr.onload = function () { 
   if(xhr.status >= 200 && xhr.status < 300 || xhr.status == 304) {
     console.log(xhr.responseText)}
     }
   }
- 
loadend 在通信完成或者触发 error、 abort、 load 事件后触发 
超时
当请求长时间处于请求状态时,可以设置 timeout 来设置等待多少毫秒后终止请求,这个等待多少响应时间是由从send()后开始
var xhr = new XMLHttpRequest()
xhr.open('POST',url)
xhr.timeout = 1000 // 设置超时时间
// 当达到超时时间触发下面的事件
xhr.ontimeout = function() {
  console.log("请求超时!")
}
xhr.onload = function () {
  if(xhr.status>=200 && xhr.status<300 || xhr.status == 304) {
  console.log(xhr.responseText)
  }else {
    console.log("error" + xhr.staus)
  }
}
如何封装一个ajax
思路: 考虑到传入参数有:请求的类型,请求的主体,响应数据类型需不需要进行响应解码,比如如果是json类型需不需要对其解析( JSON.parse( ) ),成功后的回调函数,错误时的函数,还有对于请求的查询字段来说需要为键值对加上&
// 传入一个对象,包含所需的参数,必选的url、请求类型、
function ajax(opts) {
    var url = opts.url
    //请求类型
    var type = opts.type || 'GET'
    // 响应数据类型
    var getData = opts.getData || 'json'
    //成功回调函数
    var onsuccess = opts.onsuccess || function () {}
    // 失败回调函数
    var onerror = opts.onerror || function () {}
    // 查询字符串
    var resData = resData || {}
    var dataStr = []
    for (key in resData) {
        // 为查询字符串编码
        key = encodeURIComponent(key)
        resData[key] = encodeURIComponent(resData[key])
        // 将其变为 Key1=value,key2=value2 格式存入dataStr
        dataStr.push(key + '=' + resData[key])
    }
    // join()方法将其转换为 'Key1=value&key2=value2'的字符串
    dataStr = dataStr.join('&')
    if (type == 'GET') {
        url += dataStr
    }
    var xhr = new XMLHttpRequest()
    xhr.open(type, url, true)
    xhr.onload = function () {
        if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
            if (getData === 'json') {
                onsuccess(JSON.parse(xhr.responseText))
            } else {
                onsuccess(xhr.responseText)
            }
        } else {
            //出错调用函数
            onerror()
        }
    }
    // 为请求出错事件设置函数
    xhr.onerror = onerror
    //判断如果是'POST'类型在send()上添加请求查询字符串
    //如果是'GET'直接发送请求,因为查询字符串拼接到了url上
    if (type === 'POST') {
        xhr.send(dataStr)
    } else {
        xhr.send()
    }
}
ajax({
    url: 'http://api.douban.com/v2/movie/top250',
    data: {
        start: 0,
        count: 10
    },
    onsuccess: function (ret) {
        console.log(ret)
    },
    onerror: function () {
        console.log('服务器异常')
    }
})
 
                
            
         
 
         浙公网安备 33010602011771号
浙公网安备 33010602011771号