# 27、AJAX基础知识

什么是AJAX

async javascript and xml(异步的JSXML

客户端JS中的方法,用来向服务器端发送请求(还可以传递给服务器端数据),然后把服务器端返回的内容获取到(一般运行在客户端的浏览器中的)。

XML:可扩展的标记语言(一种数据格式)

利用自己扩展的有规则的标记来存储相关数据的

# 异步的JS

这里的异步不是说AJAX只能基于异步进行请求,这里的异步特指的是局部刷新

# 全局刷新

全局刷新

所谓的全局刷新就是页面中的每次数据更新,都会从服务器获取到最新的已经渲染好的源代码,然后拿到浏览器中进行展示;

[优势]

  • 1)动态展示的数据在页面的源代码中可以看见,有利于SEO优化推广(有利于搜索引擎的收录和抓取)
  • 2)从服务器获取的结果就已经是最后要呈现的结果了,不需要客户端做额外的事,所以页面加载速度快,(前提是服务器端处理的速度够快)如淘宝、京东的首屏数据一般都是由服务器端渲染

[弊端]

  • 1)页面中的数据需要实时更新,即使是一张小图片更新,每次也都需要重新刷新一次。
  • 2)都交给服务器端做数据渲染,服务器端的压力大,如果服务器处理不过来,页面呈现的速度更慢
  • 3)全局刷新不利于开发(开发效率低)

# 局部刷新

局部刷新

前后端完全分离的项目,页面中需要动态绑定的数据是交给客户端完成渲染的:客户端渲染要以下步骤:

  • 1、向服务器端发送AJAX请求
  • 2、把从服务器端获取的数据解析处理,拼接成为我们需要展示的HTML字符串
  • 3、拿拼接好的字符串替换页面中某一部分需要更新的内容(局部刷新),页面整体不需要重新加载,局部渲染即可

[优势]

  • 1、我们可以根据需求,任意修改页面中某一部分内容(如实时刷新),整体页面不刷新,性能好,体验好(所有表单验证、需要实时刷新的需求都要基于AJAX实现) -2、有利于开发,提高开发效率
    • 1)前后端的完全分离,后台不需要考虑前端如何实现,前端也不需要考虑后台用什么技术,真正实现了前后端分离
    • 2)可以同时开发:项目开发开始,先制定前后端数据交互的接口文档(文档中包含了调取哪个接口或者哪些数据等协议规范),后台把接口写好,客户端按照接口调取即可,后台再去实现接口功能即可;

[弊端]

  • 1、不利于SEO优化:第一次从服务器端获取的内容不包含需要动态绑定的数据,不利于SEO收录,后期通过JS添加到页面中的内容,并不会写到源代码中
  • 2、由于需要动态绑定数据后,再交给浏览器渲染。所以没有服务器渲染页面呈现速度快;

# 基于原生JS实现AJAX

// Ajax四步:
let xhr=new XMLHttpRequest();
xhr.open("get","/data.txt",false);
xhr.onreadystatechange=function(){
	if(xhr.readyState===4&&/^2\d{2}$/.test(xhr.status)){
		var val=xhr.responseText;
	}
};
xhr.send(null);

# AJAX请求方式

# AJAX第一步

let xhr=new XMLHttpRequest

创建一个AJAX对象,IE6以下不支持;

# AJAX第二步:

TIP

xhr.open(method,url,async,username,userpass) 第二步代表发送前的基本信息配置(并没有发送请求)。open方法中的参数详解如下:

  • method:请求方式(以下方法都可以从服务器获取数据,也可以向服务器传递数据)
    • GET:一般用于从服务器获取数据(也可以向服务器发送数据)
    • POST:一般用于向服务器推送数据
    • PUT:用于给服务器上增加资源文件(上传图片)
    • DELETE:用于从服务器上删除资源文件
    • HEAD:用于只获取服务器的响应头信息
  • url:请求的URL地址(配置向哪一个服务器地址发送请求)
  • async:是否为异步(true代表异步,false代表同步,默认为true)
  • 用户名和密码:这两个参数一般不用,如果你请求的·地址所在的服务器设定了访问权限,则需要我们提供可通行的用户名和密码,才可以(一般服务器都是可以允许匿名访问的)

总结:

GET与POST区别:

  • 1、大小问题:GET请求传递给服务器的内容大小存在限制而POST理论上没有限制。存在限制的原因是 浏览器对URL的长度存在限制。各浏览器都有自己的URL最大长度限制(谷歌:8KB,火狐:7KB,IE:2KB),超出的部分会被截取;而POST请求一般都是基于 设置请求主体来实现的,理论上POST通过请求主体传递是没有大小限制的;
  • 2、速度的问题:与 GET 请求相比,POST请求消耗的资源会更多一些。从性能角度来看,以发送相同的数据计,GET请求的速度最多可达到POST请求的两倍
  • 3、缓存的问题:GET请求会出现缓存(这个缓存不一定是304),会产生缓存是因为GET请求是通过URL问号传参来实现数据传递的(浏览器会根据每次请求时的URL地址与上次请求的地址是否相同,来判定是读取上次请求的缓存,还是再请求一次拿到最新数据);POST是没有缓存的。如何解决GET请求出现缓存:在URL的末尾追加一个随机数;
$.ajax({
  url:''+Math.random()
})
  • 4、安全问题: 一般来说GET不安全,GET请求是通过URL传参把数据传递给服务器,用户名和密码将明文出现在URL上,而黑客可通过URL劫持获取到get请求问号传参传递的内容。数据不太安全而POST相对安全一些

# AJAX第三步

TIP

xhr.onreadystatechange=function(){} 此步骤作用:监听AJAX状态改变,获取响应信息(获取响应头信息、获取响应主体信息)

xhr.onreadystatechange=function(){
	if(xhr.readyState===4&&/^2\d{2}$/.test(xhr.status)){
		var val=xhr.responseText;
	}
}

# AJAX第四步:

xhr.send(null)

这一步才算发送请求:参数是请求主体中需要传递给服务器的内容

向服务器发送请求的任务,才算开始;

# xhr.readyState

AJAX状态码,代表当前AJAX处理的进度

可能的值如下:

  • 0 :UNSENT 当前的请求还没发送(未调用open方法)
  • 1 :OPENED URL地址已经打开(已调用open方法未调用send方法)
  • 2 :HEADERS_RECEIVED 当前AJAX的请求已经发送,并且已经接收到服务器端返回的响应头信息了(已经调用send方法,2的时候就已经可以拿到响应头信息了)
  • 3 :LOADING 已经接收到部分响应数据
  • 4 :DONE 响应主体的内容已经成功返回到客户端

# xhr.status

HTTP网络状态码,描述了当前服务器返回信息的状态,

可能的值如下:

  • 200 或者^2\d{2}: (200或以2开头的)都代表响应主体的内容已经返回成功

  • 以3开头的也算请求成功,只不过服务器端做了很多特殊的处理

    • 301:永久重定向/永久转移(一般用于域名迁移)
    • 302:临时重定向/临时转移(一般用于服务器的负载均衡,当服务器访问量过大,就把当前的请求临时交给其他服务器处理)
    • 303:表示请求的资源路径发生改变,使用GET方法请求新url。她与302的功能一样,但是明确指出使用GET方法请求新url
    • 304:本次获取的内容是读取缓存中的数据(把一些不经常更新的文件或者内容缓存到浏览器中,下一次从缓存中获取,减轻服务器压力,也提高了页面加载速度)
    • 307: 表示请求的资源路径临时发生改变,要求浏览器后续的请求应仍使用原本的method。可以确保请求方法和消息主体不会发生变化。
    • 308: 表示请求的资源路径永久性的发生改变,要求浏览器后续的请求应仍使用原本的method。可以确保请求方法和消息主体不会发生变化。
  • 以4开头的一般都是失败,而且客户端的问题偏大

    • 400:客户端传递给服务器端的参数出现错误
    • 401:无权限访问
    • 404:要访问地址不存在
  • 以5开头的一般都是失败,而且服务器端的问题偏大

    • 500:未知的服务器错误
    • 503:服务器已经超负荷

不同状态码对于SEO的影响

  • 301:当旧页面已经被收录了,使用301跳转到新的页面上,搜索引擎会把旧页面删除,替换成新的页面,并把旧页面的权重排名转移到新页面上,平稳过度。
  • 302:和301的区别在于不会删除旧页面,但是会收录新的页面,不会将旧页面的权重排名转移到新的页面。
  • 304:页面长时间出现大量304的状态码,会影响搜索引擎的信任度,会导致抓取频率和次数下降,页面内容收录速度表面,甚至不收录,网站快速更新变慢,甚至停止快照。网站的关键词排名下降,影响网站权重也下降。

# xhr.responseText

接收到的响应主体中的内容;

# AJAX属性

属性

  • readyState:存储的是当前AJAX的状态码
  • response/responseText/responseXML:都是用来接收服务器返回的响应主体中的内容,只是格式不一样
    • responseText:是最常用的,接收到的结果是字符串格式的(一般服务器返回的数据都是JSON格式字符串)
    • responseXML偶尔会用到,如果服务器返回的是XML文档数据,需要用此属性接收
  • status:服务器返回的HTTP状态码
  • statusText:对返回状态码的描述
  • timeout:设置当前AJAX请求的超时时间,表示请求在等待响应多少毫秒之后就终止。在给timeout 设置一个数值后,如果在规定的时间内浏览器还没有接收到响应,那么就会触发 timeout事件

# AJAX方法

方法

  • abort:强制中断AJAX请求
  • open:打开一个URL地址
  • send:发送AJAX请求(参数是请求主体中传递给服务器的内容)
  • getAllResponseHeaders:获取全部的响应头信息(结果为字符串文本)
  • getResponseHeader(key):获取指定属性名的响应头信息
  • setRequestHeader(key,value):设置请求头信息(可以是自定义的请求头)
  • overrideMimeType:重写数据的MIME类型

# AJAX事件

事件

  • onabortAJAX被中断触发此事件
  • onreadyStateChangeAJAX状态发生改变触发此事件
  • ontimeout:请求超时后触发此事件

# JS中常用的编码解码方法

TIP

正常的编码解码(非加密)

  • 1、escape / unescape:主要就是把中文汉字进行编码和解码(一般只有JS语言支持:常用于前端页面通信时候的中文汉字编码)
  • 2、encodeURI / decodeURI:基本上所有的编程语言都支持;
  • 3、encodeURIComponent / decodeURIComponent:使用对应的编码替换所有非字母数字字符。

encodeURI与encodeURIComponent的区别:

encodeURI()编码后的结果是除了空格之外的其他字符都原封不动,只有空格被替换 。而 encodeURIComponent()方法则会使用对应的编码替换所有非字母数字字符。

加密编码解码

  • 1、可逆转加密(一般都是自己定规则)
  • 2、不可逆转加密(基于MD5加密完成,为了安全一般都进行二次加密)
let str = 'http://www.baidu.com/?',
	obj = {
		name:'我在哪',
		age:9,
		url:'http://www.baidu.com/?lx=1'
	};
//=>把OBJ中的每一项属性名和属性值拼接到URL的末尾(问号传参方式)
for(let key in obj){
	str+=`${key}=${encodeURIComponent(obj[key])}&`;
	//=>不能使用encodeURI必须使用encodeURIComponent,原因是encodeURI不能编码特殊的字符
}
console.log(str.replace(/&$/g,''));

//=>后期获取URL问号参数的时候,我们把获取的值在依次的解码即可
String.prototype.myQueryUrlParameter=function myQueryUrlParameter(){
	let reg=/[?&]([^?&=]+)(?:=([^?&=]*))?/g,
	obj={};
	this.replace(reg,(...arg)=>{
    let [,key,value]=arg; 		
    obj[key]=decodeURIComponent(value);//=>此处获取的时候可以进行解码	
	});
	return obj;
}

# AJAX中的同步异步

TIP

Ajax中的同步:当AJAX任务开始的时候,直到readyState为4的时候任务才结束,此时才可以处理其他的事情;

Ajax中的异步:当AJAX任务开始的时候,不需要等到readyState为4我依然可以继续做其他的任务,并且只有当其他的任务完成后,我们再看readyState是否等于4,到4再做相关操作; 倒计时抢购时间差如何处理,在异步ajax请求readyState=2的时候拿到服务器时间,减少时间差。

# 倒计时抢购

let getSeverTime=function () {
  let xhr=new XMLHttpRequest();
  xhr.onreadystatechange=function () {
    /*以2或3开头都算获取成功*/
    if(!/^(2|3)\d{2}$/.test(xhr.status))return;
    if(xhr.readyState===2){
        /*只在第一次的时候获取服务器的时间,下次直接在其基础上+1就行*/
        severTime=new Date(xhr.getResponseHeader("date")).getTime();
    }
  };
  /*尽可能的减少时间差*/
  /*只获取响应头信息即可,所以请求方式使用head即可,head请求中状态码没有3,因为不需要等待接收响应主体内容*/
  xhr.open('head','json/banner.txt',true);
  //只能使用异步,同步的时候无法在状态为2或3的时候做处理,而我们要获取响应头信息,在状态为2的时候就可以获取了,所以需要异步
  xhr.send(null);
};

# jQuery中的AJAX

$.ajax({
  url:'xxx.txt',
  method:'get',
  /*dataType只是我们预设获取结果的类型,无法影响服务器传递给我们的类型,只能拿到服务器的数据后,jQuery再进行转化*/
  dataType:'json',
  /*是否清除缓存*/
  cache:true,
  /*同步还是异步 false代表同步*/
  async:true,
  /*我们可以通过data属性把一些信息传递给服务器;get方式通过问号传参,post通过设置请求主体*/
  /*data的值可以为:字符串、对象,如果是对象,JQ会把对象转化为xxx=xxx&xx=xx 这种字符串传递给服务器*/
  data:null,
  success:function (result) {
    /*请求成功后(xhr.readyState为2或3开头)才会触发此函数*/
  },
  complete:function () {
    /*不管请求是否成功都会触发此函数*/
  }
})
上次更新: 7/6/2021, 10:33:32 PM