闲话不多说,直接代码解释
function ceshi(){
var json = {name:"caililiang",age:25};
$.ajax({
url:"com.renhe.raphael.renhe.Test.biz.ext",
type:"POST",
data:JSON.stringify(json),
async:false,//默认值: true
cache: true,//默认值: true,浏览器有可能从它的缓存中调取数据
contentType:'text/json',//默认值: "application/x-www-form-urlencoded"。发送信息至服务器时内容编码类型,经常会因为这个不设置导致前端的数据传送到服务器,不被服务器识别,而让用户感觉前端数据没有传到服务器。
dataType:"text/json",//预期服务器返回的数据类型,可不传进行自动识别
timeout:2000,//设置请求超时时间(毫秒)。此设置将覆盖全局设置
username:"caililiang",//用于响应 HTTP 访问认证请求的用户名
password:"000000",//用于响应 HTTP 访问认证请求的密码
ifModified:true,//默认为false。仅在服务器数据改变时获取新数据。服务器数据改变判断的依据是Last-Modified头信息。默认值是false,即忽略头信息。
global:false,//默认为true。表示是否触发全局ajax事件。设置为false将不会触发全局ajax事件,ajaxStart和ajaxStop可用于控制各种ajax事件
beforeSend:function(XMLHttpRequest){
this;//调用本次ajax请求时传递的options参数
debugger;alert("beforeSend,在发送请求之前调用");
return true;},//如果返回 false 可以取消本次 ajax 请求。
dataFilter:function(data,type){alert("dataFilter,在请求成功之后调用");},//提供data和type两个参数。data是Ajax返回的原始数据,type是调用jQuery.ajax时提供的dataTYpe参数
success:function(data,textStatus){alert("seccess,当请求之后调用。传入返回后的数据,以及包含成功代码的字符串");},
error:function(XMLHttpRequest,textStatus,errorThrown){alert("error,在请求出错时调用");},
complete:function(XMLHttpRequest,textStatus){alert("complete,当请求完成之后调用这个函数,无论成功或失败");}
});
}
ajaxStart()与ajaxStop():当Ajax请求开始时,会触发ajaxStart()方法的回调函数。当Ajax请求结束时,会触发ajaxStop()方法的回调函数。这些方法都是全局的方法,因此无论创建它们的代码位于何处,只要有Ajax请求发生时,就会触发它们。
有时候页面需要加载一些图片,可能速度会比较慢,如果在加载过程中,不给用户提供一些提示和反馈信息,很容易让用户误认为按钮单击无用,使用户对网站失去信息。此时,我们就需要为网页添加一个提示信息,常用的提示信息是“加载中...”,代码如下:
界面:<div id="loading">加载中...</div>
当Ajax请求开始时,将此元素显示,用来提示用户Ajax请求正在进行;当Ajax请求结束后,将此元素隐藏。代码如下:
$("#loading").ajaxStart(function(){
$(this).show();
}).ajaxStop(function(){
$(this).hide();
})
注意同步异步属性async的使用:
如$.ajax({
url,
type,
data,
async,
success:function(){
successfunction();
}
});
afterfunction();
如果async为true,表示异步处理,则afterfunction()不用等待ajax的执行,如果async为false,表示同步处理,则afterfunction()需要等待ajax执行完才能开始执行(afterfunction()会在successfunction()后面执行);特别注意:在js里最页面渲染时,页面操作默认是在页面主线程执行完之后才执行的,因此在做类似setAttribute()操作时会经常出现“不可理解”的问题,如在做遮罩时(某个操作前弹出遮罩,完成操作之后隐藏遮罩),如果这样写:
显示遮罩();
$.ajax({
url,
type,
data,
async:false,
success:function(){
隐藏遮罩();
}
});
则会出问题,此地是同步,按理是先显示遮罩,然后ajax执行完之后再隐藏遮罩,但实际上却页面不会出现任何的遮罩现象,原因是显示操作调用后不能立马生效,必须等到页面主线程处理完,此时主线程在等ajax执行,等到ajax执行完之后就执行了隐藏遮罩,最后主线程完成之后,再顺序处理渲染命令,两条命令几乎同时执行,则页面就看不到遮罩效果了,此时若把async改为true就可以正常显示遮罩了。
如果下面这样写也会有问题:
显示遮罩();
$.ajax({
url,
type,
data,
async:false,
success:function(){
}
});
隐藏遮罩();
这里,不管async的值为true还是false,遮罩效果都出不来,因为不管同步还是异步,显示遮罩和隐藏遮罩都是在主线程中,都是在主线程执行完后才执行任务,两条命令几乎同时执行,因此看不出效果。
正确的做法是用ajax回setTimeout函数实现前端的多线程操作,一次页面渲染操作在主线程做,一次操作在子线程中处理,这样才能实现页面的两次渲染在两个不同的时间点上进行
原理:
深入研究浏览器内核可以发现,浏览器内核是多线程的,其中一个常驻线程叫javascript引擎线程,负责执行js代码,还有一个常驻线程叫GUI渲染线程,负责页面渲染,dom重画等操作。javascript引擎是基于事件驱动单线程执行的,js线程一直在等待着任务列表中的任务到来,而js线程与gui渲染线程是互斥的,当js线程执行时,渲染线程呈挂起状态,只有当js线程空闲时渲染线程才会执行。所以,我们可以理解为什么dom更新总是不能被立刻执行。就我们的代码来说,显示提示和隐藏提示的dom操作都被浏览器记下来了并放在gui渲染线程的任务队列中,但都没有立刻进行渲染,而是在当前函数完成后(js线程已处于空闲状态),进行最终的dom渲染,而我们的用户则基本感受不到这个过程,因为经过show和hide两个相反的操作,相当于dom完全没变。