Ajax异步操作学习日志
在同步请求中,浏览器通常都是直接想服务器请求数据并直接接收、处理数据,而在这期间,我们只能干等着服务器处理请求,什么也做不了。
基于同步请求模式,异步请求是将请求交给代理对象"XMLHttpRequest",由该代理对象向服务器发送请求,并接收处理数据,最后返回到浏览器组件中,实现页面的局部刷新。异步请求让我们的浏览器不会等待服务器处理请求,不需要重构整个页面请求响应的数据,在请求的过程中浏览器还可以进行其他操作
原生Ajax实例的创建
- 一般来讲,我们通过构造方法来创建一个 XMLHttpRequest对象。如下所示
let xhr=new XMLHttpRequest()
- 该对象拥有属于自己的属性和方法
- open(“get”,“url”,is)方法,创建相应的需求,需要提供请求的类型,请求的地址,以及是否异步(必须异步,默认为true。so,可以省略)
- send()方法,将请求发出。
- onreadystatechange 事件,该事件实时监听请求过程,在请求的各个阶段反馈信息。
- onload()方法,当Ajax状态从准备状态改变(请求完成)时触发返回请求状态。
- onload与onreadystatechange的区别,前者用于返回Ajax执行完成后的状态,而后者则从一开始便监听Ajax的状态(后者不适用于promise对象中,因为promise对象的状态一旦确定就不可以改变)
- responseText,服务器的响应,返回数据的文本。
- statusText,服务器返回的状态文本信息
- 请求类型(get请求和post请求)
- get请求,直接请求数据
- post请求,先发送数据,在请求反馈
- get比post更快,适用于小数据请求
- post相对于处理更多的数据更加稳定,也适用于向服务器发送大量数据。
- post请求往往需要向后台发送数据。转化成JSON串.
一般的post请求的数据是一个JSON串,我们拿到后不可以直接输出,需要使用 JOSN.parse(JOSN串) 方法将其转化为对象。
与之相反,我们也可以使用JSON.StringFY(对象),把对象转化成一个JSON串。
- 状态字
- readyState,表示请求的状态。
- 0 = 未初始化,1 = 正在加载,2 = 已加载,3 = 交互中,4 = 完成
- status,服务器的HTTP状态码(如:404 = “文件末找到” 、200 =“成功” ,等等)
- Ajax实例演示
let xhr=new XMLHttpRequest();
xhr.open("POST","http://localhost:3008/posts")
xhr.setRequestHeader("Content-type","application/json")
xhr.send(JSON.stringify({
"title": "第嘉 react 基础教程",
"author": "小hong"
}))
xhr.open("get","http://localhost:3008/posts?id=2")
xhr.send();
xhr.onreadystatechange=function(){
if(xhr.readyState==4 && xhr.status==200){
console.log( JSON.parse(xhr.responseText)[0].author);
}
}
- Ajax的优点
- 无刷新更新数据。
- 异步与服务器通信
- 前端和后端负载平衡
- 界面与应用分离
- Ajax的缺点
- .AJAX的缺点
- .AJAX干掉了Back和History功能,即对浏览器机制的破坏。
在动态更新页面的情况下,用户无法回到前一个页面状态,因为浏览器仅能记忆历史记录中的静态页面。一个被完整读入的页面与一个已经被动态修改过的页面之间的差别非常微妙;用户通常会希望单击后退按钮能够取消他们的前一次操作,但是在Ajax应用程序中,这将无法实现。
后 退按钮是一个标准的web站点的重要功能,但是它没法和js进行很好的合作。这是Ajax所带来的一个比较严重的问题,因为用户往往是希望能够通过后退来 取消前一次操作的。那么对于这个问题有没有办法?答案是肯定的,用过Gmail的知道,Gmail下面采用的Ajax技术解决了这个问题,在Gmail下 面是可以后退的,但是,它也并不能改变Ajax的机制,它只是采用的一个比较笨但是有效的办法,即用户单击后退按钮访问历史记录时,通过创建或使用一个隐 藏的IFRAME来重现页面上的变更。(例如,当用户在Google Maps中单击后退时,它在一个隐藏的IFRAME中进行搜索,然后将搜索结果反映到Ajax元素上,以便将应用程序状态恢复到当时的状态。)
但是,虽然说这个问题是可以解决的,但是它所带来的开发成本是非常高的,并与Ajax框架所要求的快速开发是相背离的。这是Ajax所带来的一个非常严重的问题。
一 个相关的观点认为,使用动态页面更新使得用户难于将某个特定的状态保存到收藏夹中。该问题的解决方案也已出现,大部分都使用URL片断标识符(通常被称为 锚点,即URL中#后面的部分)来保持跟踪,允许用户回到指定的某个应用程序状态。(许多浏览器允许JavaScript动态更新锚点,这使得Ajax应 用程序能够在更新显示内容的同时更新锚点。)这些解决方案也同时解决了许多关于不支持后退按钮的争论。 - AJAX的安全问题。
AJAX 技术给用户带来很好的用户体验的同时也对IT企业带来了新的安全威胁,Ajax技术就如同对企业数据建立了一个直接通道。这使得开发者在不经意间会暴露比 以前更多的数据和服务器逻辑。Ajax的逻辑可以对客户端的安全扫描技术隐藏起来,允许黑客从远端服务器上建立新的攻击。还有Ajax也难以避免一些已知 的安全弱点,诸如跨站点脚步攻击、SQL注入攻击和基于Credentials的安全漏洞等等。 - 对搜索引擎支持较弱。
对搜索引擎的支持比较弱。如果使用不当,AJAX会增大网络数据的流量,从而降低整个系统的性能。 - 破坏程序的异常处理机制。
至 少从目前看来,像Ajax.dll,Ajaxpro.dll这些Ajax框架是会破坏程序的异常机制的。关于这个问题,曾在开发过程中遇到过,但是查了一 下网上几乎没有相关的介绍。后来做了一次试验,分别采用Ajax和传统的form提交的模式来删除一条数据……给我们的调试带来了很大的困难。 - .违背URL和资源定位的初衷。
例如,我给你一个URL地址,如果采用了Ajax技术,也许你在该URL地址下面看到的和我在这个URL地址下看到的内容是不同的。这个和资源定位的初衷是相背离的。 - AJAX不能很好支持移动设备。
一些手持设备(如手机、PDA等)现在还不能很好的支持Ajax,比如说我们在手机的浏览器上打开采用Ajax技术的网站时,它目前是不支持的。 - 客户端过肥,太多客户端代码造成开发上的成本。
编写复杂、容易出错 ;冗余代码比较多(层层包含js文件是AJAX的通病,再加上以往的很多服务端代码现在放到了客户端);破坏了Web的原有标准。、
- .AJAX干掉了Back和History功能,即对浏览器机制的破坏。
上述缺点部分转载自博客园 作者:Otgs .
- 使用原生的 Ajax 发送 post 请求的时候,需要告知请求头(告知后台我传递的数据类型)
xhr.setRequestHeader("Content-type","application/json") 设置请求头
jQuery 中使用 AJAX
$.ajax() $.get(), $.post(),三个最常用。
- get 请求, get 传递参数可以写在?后,也可以写在 get 的第二个参数中,以对象方式传递。
$.get("url",{参数},回调函数)
- ajax()
$.ajax({ url:"url", type:"get",请求类型 data:{},参数 success:function(data){},请求成功回调函数 error:function(err){},请求失败毁掉函数 complete:function(){},请求完成回调函数 })
- 实例演示
$.ajax({
url:'http://localhost:3008/posts',
type:"GET",
data:{id:2},
success(data){
console.log("请求成功");
console.log(data);
},
error(err){
console.log("请求失败");
},
complete(){
console.log("请求完成");
}
})
axios(未来常用)
- 参考网址:$(http://www.axios-js.com/zh-cn/docs/)
- cdn:
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
- get()和 post()使用源码\
axios.get('http://localhost:3008/posts',{params:{id:1}})
.then( res=>{console.log(res);} )
.catch( err=>{console.log(err);} )
axios.post('http://localhost:3008/posts',{ title:'react 源码', author:'小李' })
.then(res=>{console.log(res)})
.catch(err=>{console.log(err);}) `
请求成功时执行then,请求失败之心catch
-
axios.all([]),数组中可以加入多条请求
-
提取公共的 axios 配置
-
方案一:配置实例
const my_axios=axios.create({ baseURL:"http://localhost:3008", timeout:1000 }) my_axios.get('/posts').then().catch();
-
方案二,根据 api 配置默认值
axios.defaults.baseURL='http://localhost:3008'; axios.get('/posts').then
-
axios 拦截器
// 添加请求拦截器
axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
// 添加响应拦截器
axios.interceptors.response.use(function (response) {
// 对响应数据做点什么
return response;
}, function (error) {
// 对响应错误做点什么
return Promise.reject(error);
});
下次内容,Promise对象(一种异步编程的解决方案)。