本文主要是我学习ajax的笔记,不涉及到原理,只是记录如何使用。如果有错欢迎各位大佬指出。提前先转一篇写的非常全面的博客你真的会使用XMLHttpRequest吗?

一、ajax概念

1、ajax是Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。它依赖的是现有的CSS/HTML/Javascript,ajax依靠浏览器提供的XMLHttpRequest对象让浏览器发出HTTP请求与接收HTTP响应,实现在页面不刷新的情况下和服务端进行数据交互

2、依靠对象
XMLHttpRequest对象
fetch对象 (兼容性较弱)

二、采用同步的方式通过ajax获取数据(简单版)

1、代码

我在当前html文件下伪造了一个hello.json的文档,作为服务器资源。

<script>
 var xhr =new XMLHttpRequest() //生成一个新的XMLHttpRequest对象
 xhr.open('GET','hello.json',false)//第一个参数是请求获取数据的方式,第二个参数是请求服务器对应地址,参数三是false是同步获取,true是异步获取
 xhr.send()
 var data= xhr.responseText
 console.log(data)
</script>

控制台报错,显示用file协议是不支持的,跨源请求仅支持http, data, chrome, chrome-extension, https协议方案
clipboard.png
所以我们打开终端gitbash,切换到html当前文件下,输入http-server打开本地服务器

clipboard.png
打开服务器后,返回两个地址,125的地址是本地局域网环境的 ip,127的ip是本机 ip。
这两个地址的区别,可以点击这个链接查看
复制这个IP地址到浏览器上,打开对应的html文件,得到了对应的ajax数据

clipboard.png

2、总结:

采用同步的方式,也能获得数据,但是时间比较长,差不多22ms(个人电脑上的数据,并非实验数据),效率不高。
把参数三把false改成true,就可以变异步。xhrsend之后立刻就执行返回数据的操作,导致没有数据返回。
如果需要采用异步的方式获取ajax数据,就需要绑定load事件,等加载后再执行var data= xhr.responseText,才返回数据

三、采用异步绑定事件的方式获取ajax数据

1、代码

异步绑定数据,需要绑定load事件

 var xhr =new XMLHttpRequest()
//     xhr.open('GET','hello.json',true)
//     xhr.send()
//     xhr.addEventListener('load',function(){
//     var data= xhr.responseText
//     console.log(data)
//     console.log(xhr.status)
//     })  

四、xhr.status

1、概念

status是XMLHttpRequest对象的一个属性,表示响应的HTTP状态码。
该状态码用于表示特定 HTTP 请求是否已成功完成,这个状态码是服务器发给浏览器的

2、status数值分类

clipboard.png

3、所有status其余状态码

这篇博客(Ajax关于readyState(状态值)和status(状态码)的研究) 上写status其余状态码比较详细
也可以查阅mdn,我这里只是挑出几个常用的状态码
3.1) 200 请求成功。成功的含义取决于HTTP方法:

  • GET:资源已被提取并在消息正文中传输。
  • HEAD:实体标头位于消息正文中。
  • POST:描述动作结果的资源在消息体中传输。
  • TRACE:消息正文包含服务器收到的请求消息

3.2)404 Not Found
请求失败,被广泛应用于当服务器不想揭示到底为何请求被拒绝或者没有其他适合的响应可用的情况下。

3.3)304 Not Modified(未改变)
如果客户端发送了一个带条件的 GET 请求且该请求已被允许,而文档的内容(自上次访问以来或者根据请求的条件)并没有改变,则服务器应当返回这个状态码
未改变说明无需再次传输请求的内容,也就是说可以使用缓存的内容

4、举个例子

var xhr= new XMLHttpRequest()
xhr.timeout=13
// 注意timeout时间要根据收到json文件响应时间来设置,小于这个时间会输出timeout
xhr.open('GET','hello.json',true)
xhr.send()

xhr.addEventListener('load',function(){
    console.log(xhr.status)
    if((xhr.status>=200 && xhr.status<300)||xhr.status==304){
        console.log(this.responseText)
    }else{
        console.log('fail')
    }
})
xhr.ontimeout=function(e){
    console.log('timeout')
}
xhr.onerror=function(){
    console.log('error')//一般是连接失败报错
}

坑1:onerror和status中的错误状态的区别
onerror是定义一个事件,当ajax连接失败(浏览器发送ajax请求根本没有连接到服务器)浏览器自己输出error。status是请求链接到服务器,服务器响应错误后服务器返回浏览器的状态码。详情可以查看这个链接
坑2:XMLHttpRequest提供了timeout的属性,为了防止请求过了很久还没有成功,白白占用的网络资源。timeout是指响应时间,开始请求到接收到响应(开始处理)的时间,单位为ms。
比如我设置timeout时间为5ms
clipboard.png
结果请求超时,返回的是timeout
clipboard.png

timeout对应console台,应该是以下红框的总时间。

clipboard.png
timing时间各个时间解析

clipboard.png

五、readystate

1、概念

XMLHttpRequest 的一个属性,用来表示当前XMLHttpRequest对象处于什么状态
有5个值,mdn的解析

0 初始化,XMLHttpRequest对象还没有完成初始化(但尚未调用 open() 方法)
1 载入,XMLHttpRequest对象开始发送请求
2 载入完成,XMLHttpRequest对象的请求发送完成
3 下载解析中,XMLHttpRequest对象开始读取服务器的响应
4 完成,XMLHttpRequest对象读取服务器响应结束

2、举个例子

var xhr= new XMLHttpRequest()
xhr.open('GET','hello.json',true)
xhr.send()
xhr.onreadystatechange = function(){
    if(xhr.readyState === 4){
// redyState的s一定要大写,不然不输出,但绑定事件的onreadystatechange是小写
        if((xhr.status>=200 && xhr.status<300 ) ||xhr.status==304){
        console.log(xhr.responseText)
    }else{
        console.log('fail')
    }}  
}

执行结果
每次readystatechange,都会触发事件,输出readystate
clipboard.png

3、坑

redyState的s一定要大写,不然不输出,但绑定事件的onreadystatechange是小写

六、get和post方式参数的位置

get方式会把参数拼装成url后

clipboard.png
post会把参数放在xhr.send()内部

var xhr = new XMLHttpRequest()
  xhr.timeout = 3000        //可选,设置xhr请求的超时时间
  xhr.open('POST', '/register', true)

  xhr.onload = function(e) { 
    if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
      console.log(this.responseText)
    }
  }
    //可选
  xhr.ontimeout = function(e) { 
        console.log('请求超时')
  }

  //可选
  xhr.onerror = function(e) {
      console.log('连接失败')
  }
  //可选
  xhr.upload.onprogress = function(e) {
      //如果是上传文件,可以获取上传进度
  }

  xhr.send('username=jirengu&password=123456')

七、封装一个 ajax对象


function ajax(opts){
    var url = opts.url
    var type = opts.type || 'GET'
    var dataType = opts.dataType || 'json'
    var onsuccess = opts.onsuccess || function(){}
    var onerror = opts.onerror || function(){}
    var data = opts.data || {}

    var dataStr = []
    for(var key in data){
        dataStr.push(key + '=' + data[key])
    }
    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(dataType === 'json'){
                onsuccess( JSON.parse(xhr.responseText))
            }else{
                onsuccess( xhr.responseText)
            }
        } else {
            onerror()
        }
    }
    xhr.onerror = onerror
    if(type === 'POST'){
        xhr.send(dataStr)
    }else{
        xhr.send()
    }
}

ajax({
    url: 'http://api.jirengu.com/weather.php',
    data: {
        city: '北京'
    },
    onsuccess: function(ret){
        console.log(ret)
    },
    onerror: function(){
        console.log('服务器异常')
    }
})

bamboo
75 声望9 粉丝

bamboo前端学习笔记