AJAX笔记

何为ajax

全称:Asynchronous JavaScript and XML。
用途: 在不重新加载页面的情况下发送请求给服务器。 接受并使用从服务器发来的数据。


常用概念

XMLHttpRequest

XmlHttpRequest是一个浏览器实现的一个接口,通过它发送一个ajax的请求(发出和接收HTTP请求),实现页面不刷新与服务端交互

var xhr = new XMLHtppRequest()
// 创建XMLHtppRequest 的实例

open( ) 方法

XMLHtppRequest 提供的open( )方法启动请求而不是立马发送,
以下是它的三个参数使用

  1. Method 请求方法: GET POST DELETE HEAD OPTIONS PUT ,通常大写
  2. url 请求url: 绝对路径和相对路径
  3. async 是否异步: 默认是true 表示异步
xhr.open("GET","/name.json")

请求头

在open() 之后设置,send()之前设置,重复设置只会 是添加而不是覆盖

xhr.setRequestHeader("Content-Type","text/plain")

发送请求 send()

发送请求方法可以没参数,特别是对GET请求

xhr.send()

以上是发送请求和数据给服务器

那么如何获得响应呢?

取得响应内容

完整的响应有状态码、响应头、响应主体组成,而XMLHttpRequest有对应的属性来使用,分别如下:

  1. statusstatusText 分别是响应的状态和状态说明 例如 200OK

  2. getResponseHeader() 和 getAllResponseHeader()查询响应头,后者过滤掉cookie头,前者当接受到"set-cookie"和"set-cookie2"" 返回null

  3. 响应主体 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下生效
FormDataArrayBufferBlobDocumentDOMStringFormDatanull
这些会让XHR对象自动为其设置相应的头部信息,具体参见你真的会使用XMLHttpRequest吗?

进度事件

  1. loadstart

    接收到响应数据的第一个字节触发

  2. progress

    在接收响应期间不断被触发

  3. error

    在请求发生错误时触发

  4. abort

调用abort() 方法时被触发

  1. load

接收到完整响应数据时触发
因为load事件是在接收到响应后就会被触发,对于相应的状态不做检查,所以需要加上检查的判断语句,且使用onload始终触发事件对象时xhr对象,所以通用。

   xhr.onload = function () { 
   if(xhr.status >= 200 && xhr.status < 300 || xhr.status == 304) {
     console.log(xhr.responseText)}
     }
   }
  1. 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('服务器异常')
    }
})

posted on 2018-07-13 01:08  2481  阅读(122)  评论(0编辑  收藏  举报

导航