Ajax从0到1
一:Ajax基本概念
Ajax 的全称是Asynchronous JavaScript and XML,其中,Asynchronous 是异步的意思,它有别于传统web开发中采用的同步的方式。XML:extensiable markup language 被称作可扩展标记语言。
简要洁说ajax就是异步的javascript
和xml
,它是一种技术方案,但是不是一种技术,其核心就是浏览器的XMLHttpRequest对象,ajax方案就是利用JavaScript操作XMLHttpRequest对象来让浏览器发出HTTP请求和响应,实现在页面不刷新的情况下和服务端数据进行交互。
XMLHttpRequest详尽解析
Ajax由下列技术组合而成:
1.使用CSS和XHTML来表示。
2.使用DOM模型来交互和动态显示。
3.使用XMLHttpRequest来和服务器进行异步通信。
4.使用javascript来绑定和调用。
Ajax的主要作用及优点:
1.最大的一点是页面无刷新,在页面内与服务器通信,给用户的体验非常好。
2.使用异步方式与服务器通信,不需要打断用户的操作,具有更加迅速的响应能力。
3.可以把以前一些服务器负担的工作转嫁到客户端,利用客户端闲置的能力来处理,减轻服务器和带宽的负担,节约空间和宽带租用成本。并且减轻服务器的负担,ajax的原则是“按需取数据”,可以最大程度的减少冗余请求,和响应对服务器造成的负担。
4.基于标准化的并被广泛支持的技术,不需要下载插件或者小程序。
二:利用Ajax和后台交互
上文多次提到了ajax的优点就是可以在页面不刷新的条件下与后台服务器进行通信提升用户的体验,那么下来我从最开始的前后端数据交互一直test到最后ajax;
01 form表单提交
<form action="/form.html" method="get">
<input type="text" name="username" placeholder="username">
<input type="password" name="password" placeholder="password" >
<input type="submit">
</form>
点击submit按钮后我们页面会刷新或者说跳转到新的页面,之所以这样就是url发生了改变假设域名本身为:127.0.0.1:8080/form.html
新的url 为:127.0.0.1/form.html?username=lay&password=12345
02 ajax
思路:
我们通过JavaScript操作浏览器自带的XMLHttpRequest
对象来和后端进行数据交互,那么该过程是异步的。我们将HTTPrequest
发送后,执行下面的代码,什么时候监听到数据返回了我们再对数据进行操作。这样就可以实现异步的数据交互。
02-1 :我们先试试同步的方式提交数据和获取数据
var xhr = new XMLHttpRequest();
//ajax第一步 ,创建XMLHttpRequest对象,
xhr.open('GET','/hello.json',false)
// open(method, url [, async = true [, username = null [, password = null]]])
// method: 请求的方式,如GET/POST/HEADER等,这个参数不区分大小写
// url: 请求的地址,可以是相对地址如example.php,
// 这个相对是相对于当前网页的url路径;也可以是绝对地址如http://www.example.com/example.php
// async: 默认值为true,即为异步请求,若async=false,则为同步请求
xhr.send();
//发送请求
var data = xhr.responseText;
//获取返回的数据
console.log(data);
http-server上测试结果:
我们可以看到数据正常输出但是会报出一个警告翻译过来就是:
主线程上的同步xmlhttpRequest由于其对最终用户体验的不利影响而被弃用。
解析:同步的请求方式假设我们发送或者请求的过程比较漫长,那么因为其是同步的是在主线程上的,所以会影响其后的操作
02-2: 竟然同步不行那么我们采用异步的方式
var xhr = new XMLHttpRequest();
xhr.open('GET','/hello.json',true);
xhr.send();
var data = xhr.responseText;
console.log(data);
结果:控制台没有输出data
解析:因为我们请求ajax是异步的所以说我们发送完数据后给data赋值返回的数据然后输出。但是没等到responseText
返回来,我们已经console.log
它了所以自然会输出空了。
于是readystatechange
和onload
来救场了
02-3: 使用document下的load事件来解决问题
var xhr = new XMLHttpRequest();
xhr.open('GET','/hello.json',true);
xhr.send();
xhr.addEventListener('load',function(){
var data = xhr.responseText;
console.log(data);
})
结果:正常获取到了数据
02-4 使用readystatechange也可以实现相同的作用
var xhr = new XMLHttpRequest();
xhr.open('GET','/hello.json',true);
xhr.send();
xhr.addEventListener('readystatechange',function(){
if(xhr.readyState === 4 && xhr.status === 200) {
//readyState: 表示数据交互是否完毕, 4表示完成
//status :表示服务器的状态是否正常 200 -->300 && 304 表示成功
var data = xhr.responseText;
console.log(data);
}
})
那么问题来了:onreadystatechange 和 onload都可以监听到数据是否获得,那么二者有何区别呢?
02-5 : 简单对比onreadystatechange 和 onload
var xhr = new XMLHttpRequest();
xhr.open('GET','/hello.json',true);
xhr.send();
console.log('readystatechange'+xhr.readyState);
xhr.onreadystatechange = function(){
console.log('readystatechange'+xhr.readyState);
}
xhr.onload = function() {
console.log(xhr.status);
if(xhr.status >= 200 && xhr.status<300 || xhr.status === 304) {
var data = xhr.responseText;
console.log(data);
}else {
console.log('error');
}
}
xhr.onerror= function() {
console.log('error');
}
结果:
解析:
我们可以看到readystatechange先于onload执行,load事件就想当于readState的值为4后触发的事件,也就是数据交互完成后触发onload,如果不需要跟踪请求返回之前的过程时,用load更加省事儿。
三:实战ajax
经过上述的理解那么我们就可以写一个ajax出来
写法一:
var xhr = new XMLHttpRequest()//
XMLHttpRequest 是一个函数通过new的方式生成一个对象
xhr.open('GET', 'http://api.jirengu.com/weather.php', true)
//open 设置参数 GRT 请求类型 'http://'请求地址 true 异步的方式
xhr.onreadystatechange = function(){
if(xhr.readyState === 4) {
if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
//成功了
console.log(xhr.responseText)
} else {
console.log('服务器异常')
}
}
}
xhr.onerror = function(){
console.log('服务器异常')
}
xhr.send()//发送请求
写法2:
var xhr = new XMLHttpRequest()
xhr.open('GET', 'http://api.jirengu.com/weather.php', true)
xhr.onload = function(){
if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
//成功了
console.log(xhr.responseText)
} else {
console.log('服务器异常')
}
}
xhr.onerror = function(){ //网络请求断了 没网络 。数据没法到达服务器
console.log('服务器异常')
}
xhr.send()
post
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=qimeng&password=123456')
封装一个ajax
function ajax(opts){
var url = opts.url
var type = opts.type || 'GET'//默认get
var dataType = opts.dataType || 'json' // 默认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('服务器异常')
}
})