// 1.创建一个ajax对象
let xhr = new AMLHttpRequest();// 不兼容IE6及更低版本的浏览器(IE6:ActiveXObject)
// 2.打开请求地址(可以理解为一些基础配置,但没有发送请求)
xhr.open([method], [url], [async], [username], [user password])
// 3.监听AJAX状态改变,获取响应信息(获取响应头信息、获取响应主题信息)
xhr.onreadystatechange=()=>{
if(xhr.readyState === 4 && xhr.status === 200){
let result = xhr.responseText; // 获取响应主体中的内容
}
};
// 4. 发送ajax请求(括号中传递的内容就是请求主体的内容)
xhr.send(null);
第二步中的知识点
xhr.open([method], [url], [async], [username], [user password])
[method]: HTTP请求方式,不管哪一种请求方式,客户端都可以传递一些信息给服务器,服务器也可以返回一些信息给客户端,GET系列以获取为主(给的少拿的多),POST系列以推送为主(给的多拿的少)
1)GET系列请求方式(获取)
- get
- delete:从服务器上删除某些资源文件
- head:只获取返回的响应头信息(不要响应主体内容)
- ...
2)POST系列请求方式(推送)
- post
- put:向服务器中增加指定的资源文件
- ...
A. 获取一些动态展示信息,一般使用GET请求,只需要向服务器端发送请求,告诉它需要的数据,服务器端就会返回需要的数据
B. 实现注册功能的时候,需要把客户输入的信息发送给服务器进行存储,服务器一般返回成功失败等状态,一般用POST请求完成
GET系列请求和POST系列下请求的区别
1、GET请求传递给服务器的内容一般没有POST请求传递的多
原因:GET请求给服务器传递内容一般都是基于url地址问号传递参数
来实现,而POST请求是设置请求主体
来实现,各浏览器对URL的长度都有限制,超过限制浏览器会自动截取,这样传递的数据就会出现缺失
理论上POST通过请求主体传递参数是没有大小限制的,真实项目中为了保证传输的速率也会限制大小(例如上传资料、图片都会做大小限制)
2、GET请求会出现缓存,POST不会出现
原因:GET通过URL传参(可能几次请求一样),POST是设置请求主体
// 每隔一分钟重新请求服务器端的最新数据展示在页面中(页面中某些数据实时刷新)
setTimeout(()=>{
$.ajax({
url: 'getUserInfo?id=123',
...
success:result=>{
// 第一次请求数据回来,一分钟后浏览器又发生一次请求,但新发送的请求跟上次一模一样,
//浏览器很有可能会直接获取上一次的数据
}
});
}, 60000);
//=> 解决方案 每次在url末尾追加一个随机数,就能保证每次请求的url不一样
// HTTP相关里头有提到
setTimeout(()=>{
$.ajax({
url: 'getUserInfo?id=123&_='+Math.random(),
...
success:result=>{
}
});
}, 60000);
3、GET请求没有POST请求安全(相对安全)
原因:还是因为GET是URL传参
URL劫持,可以把客户端传递给服务器的数据劫持掉,导致信息泄露
[url]: 请求数据的地址(API地址),真实项目中,后台开发工程师会编写一个API文档,文档汇总了获取数据需要用的地址,按照文档操作即可
[ASYNC]: 异步(SYNC同步),默认true,表示异步
[username password]: 一般不用的两个参数 若请求的URL地址所在的服务器设定了访问权限,则需要提供用户名密码,否则不需要
第三部分细节
xhr.onreadystatechange=()=>{
if(xhr.readyState === 4 && xhr.status === 200){
let result = xhr.responseText; // 获取响应主体中的内容
}
};
AJAX状态码:描述当前AJAX操作的状态
xhr.redayState0:UNSEND 未发送,只要创建AJAX对象,默认就是0
1: OPENED 执行了xhr.open这个操作
2:HEADERS_RECEIVED 当前AJAX请求已经发送,并且已经接收到服务器端返回的响应头信息
3:LOADING 响应主体内容正在返回的路上
4:DONE 响应主体内容已经返回到客户端
HTTP网络状态码,记录当前服务器返回信息的状态
xhr.status200:成功 一个完整的HTTP事务完成(以2开头的状态码一般都是成功)
以3开头的一般也是成功,只不过服务器端做了很多特殊的处理
301: Moved Permanently 永久转移(重定向)一般用于域名迁移
302: Moved Temporarily 临时转移(新的HTTP版本中307是临时重定向)一般用于服务器的负载均衡:当前服务器处理不了,把当前请求临时交给其他服务器处理
304: Not Modified 从浏览器缓存中获取数据把一些不经常更新的文件或内容缓存到浏览器中,下次可直接从缓存中获取,减轻服务器压力,提高页面加载速度
以4开头的一般都是失败,且一般都是客户端的问题(没拿到数据)
400:请求参数错误
401:无权限访问
404:访问地址不存在>以5开头的一般都是失败,且一般都是服务器端的问题(没拿到数据)
500:Internal Server Error未知的服务器错误
503:Service Unavailable服务器超载
AJAX中其他常用的属性和方法
面试题:AJAX中常用的方法有几个(AJAX总共支持几个方法)?
let xhr = new XMLHttpRequest();
console.dir(xhr);
[属性]
1、readyState:存储的是当前AJAX状态码(01234)
2、responseText/responseXML/response:都是用来接收服务器返回的响应主体的内容,只是根据服务器返回内容的格式不一样,使用不同属性接收
- responseText最常用,接收到的结果是字符串格式(服务器一般返回的都是JSON格式字符串)
- responseXML偶尔用到,若服务器端返回XML文档数据,就用这个属性接收
3、status:记录了服务器端返回的HTTP状态码
4、statusText:对返回状态码的描述(200:ok)
5、timeout:设置当前AJAX请求的超时时间,假设设置为3000(ms),3秒后响应主体内容还没返回,浏览器就会强制断开请求[方法]
1、abort():强制中断请求
2、getAllResponseHeaders():获取全部响应头信息(结果是一堆字符串文本)
3、getResponseHeader(key):获取指定属性名的响应头信息。例如getResponseHeader('date')获取响应头中存储的服务器时间
4、open():打开一个url地址
5、send():发送AJAX请求,参数客户端设置的请求主体
6、setRequestHeader(key,value):设置自定义的请求头信息[事件]
1、onabort: AJAX被中断请求时触发事件
2、onreadystatechange: AJAX状态码发生改变时触发事件
3、ontimeout: AJAX请求超时触发事件
let xhr = new XMLHttpRequest();
xhr.open('get', 'temp.json?_='+Math.random(), true);
xhr.setRequestHeader('cookie', 'cache'); //不能是汉字
// 请求头必须在open之后,send之前设置
xhr.timeout = 1;
xhr.ontimeout = () => {
console.log("请求超时");
xhr.abort();
};
xhr.onreadystatechange = () => {
let {readyState:state, status} = xhr;
// 请求成功 以2或3开头的后面两位数字
if(! (/^(2|3)\d{2}$/).test(status)) return;
// 状态为2时就可以获取头信息
if(state === 2){
let headAll = xhr.getAllResponseHeaders(),
serverDate = xhr.getResponseHeader("date");
// 时间是格林尼治时间差8小时 new Date转化为北京时间
console.log(headAll, new Date(serverDate));
return;
}
if(state === 4){
let valueText = xhr.responseText, // 获取的结果,一般都是字符串
valueXML = xhr.responseXML; //获取到XML格式数据
console.log(valueText, valueXML);
}
};
xhr.send(null);
AJAX中的同步和异步
AJAX这个任务:发送请求接收到响应主体接收完成 这个事务才算完成
let xhr = new XMLHttpRequest();
xhr.open('get', 'temp.json', false);
xhr.onreadystatechange = () => {
console.log(xhr.readyState);
// 只输出4
};
xhr.send(null);
////////分割线//////////
let xhr = new XMLHttpRequest();
xhr.open('get', 'temp.json', false);
xhr.send(null); //=> [同步]开始发送AJAX请求,任务没有完成之前下面事情做不了,
// 当xhr.readyState===4时,开始执行下面的操作
// 这个方法已经不会被触发
xhr.onreadystatechange = () => {
console.log(xhr.readyState);
// 不输出任何东西 无法获取响应主体的内容
};
////////分割线//////////
let xhr = new XMLHttpRequest();
xhr.open('get', 'temp.json'); // 第三个参数不写默认true
xhr.onreadystatechange = () => {
console.log(xhr.readyState);
// 2 3 4
};
xhr.send(null);
////////分割线//////////
let xhr = new XMLHttpRequest();
xhr.open('get', 'temp.json');
xhr.send(null);
// => xhr.readyState === 1
xhr.onreadystatechange = () => {
console.log(xhr.readyState);
// 2 3 4
};
////////分割线//////////
let xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
console.log(xhr.readyState);
//1 2 3 4
};
xhr.open('get', 'temp.json');
xhr.send(null);
////////分割线//////////
let xhr = new XMLHttpRequest();
//xhr.readyState === 0
xhr.onreadystatechange = () => {
console.log(xhr.readyState);
// 1 4
};
xhr.open('get', 'temp.json', false);
// AJAX特殊处理了一件事,状态变为1会主动执行监听方法,然后再send
// xhr.readyState === 1
xhr.send(null);
// xhr.readyState === 4 主任务队列完成
AJAX类库的封装
JQ 中的AJAX
$.ajax({
url: 'xxx.json', //=> 请求地址
method: 'get', //=> 请求方式 老版本中method和type一样
dataType: 'json', //=>只是预设获取结果的数据类型,不会影响服务器的返回
// 服务器返回的都是JSON格式的字符串
cache: false, //=>只对GET系列有作用,默认为true,
//手动设置为false, JQ会在URL的末尾追加一个随机数来清除缓存
data: null, //=>通过data可以把一些信息传递给服务器
// GET系列请求会把data的内容拼接在URL末尾传递给服务器
// POST会把data的内容放在请求主体中
// 可以是两种格式:字符串、对象,若是字符串,设置什么就传递什么;
// 若是对象,JQ会设置成"键=值"形式的字符串传递给服务器
async: true, //=>设置同步或者异步,默认true是异步
success: function(result){
//=> AJAX请求成功触发这个函数执行(readyState=4&&status==2/3开头的)
//=> result 就是获取到的结果
},
error: function(msg){
// =>请求错误触发该函数
},
complete: function(){
//=> 完成就触发,不管对或错
},
});