AJAX相关知识

AJAX基础知识

什么是AJAX?
async JavaScript and xml,异步的JS和XML。

xml:可扩展的标记语言
作用是用来存储数据的(通过自己扩展的标记名称清晰地展示出数据结构)

ajax之所以称为异步的js和xml,主要原因是:

1)xml:当初最开始用ajax实现客户端和服务器数据通信的时候,传输的数据格式一般都是xml格式的数据,所以我们把它称之为异步js和xml(现在一般都是基于JSON格式进行数据传输)。
2)异步js:这里的异步不是说ajax只能基于异步进行请求(虽然建议都是使用异步编程),这里的异步特指的是“局部刷新”

全局刷新
在非完全前后端分离项目中,前端开发只需要完成页面的制作,并且把一些基础的人机交互效果使用js完成即可,页面中需要动态呈现内容的部分,都是交给后台开发工程师做数据绑定和基于服务器进行渲染的(服务器端渲染)。
【优势】:

  • 动态展示的数据在页面的原源代码中可以看见,有利于SEO优化推广(有利于搜索引擎的收录和抓取)。

  • 从服务器端获取的结果就已经是最后要呈现的结果了,不需要客户端做额外的事情,所以页面加载速度快(前提是服务器端处理的速度够快,能够处理过来),所以类似于京东、淘宝这些网站,首屏数据一般都是经过服务器端渲染的。

【弊端】:

  • 如果页面中存在需要实时更新的数据,每一次想要展示最新的数据,页面都要重新刷新,这样肯定不行。

  • 都交给服务器端做数据渲染,服务器端的压力太大,如果服务器处理不过来,页面呈现的速度更慢(所以京东淘宝这类网站,除了首屏是服务器端渲染的,其他屏一般都是客户端做数据渲染绑定)。

  • 这种模式不利于开发(开发效率低)。

在这里插入图片描述

局部刷新
目前市场上大部分项目都是前后端完全分离的项目(也有非完全前后端分离的)。

前后端完全分离的项目,页面中需要动态绑定的数据是交给客户端完成渲染的:
1、向服务器发送AJAX请求
2、把从服务器端获取的数据解析处理,拼接成为我们需要展示的html字符串
3、把拼接好的字符串替换页面中某一部分的内容(局部刷新),页面整体不需要重新加载,局部渲染即可
【优势】:

  • 我们可以根据需求任意修改页面中某一部分的内容改变(例如实时刷新),整体页面不刷新,性能好,体验好(所以表单验证、需要实时刷新的等需求都要基于AJAX实现)。

  • 有利于开发,提高开发的效率:
    1)前后端的完全分离,后台不需要考虑前端如何实现,前端也不需要考虑后台用什么技术,真正意义上实现了技术的划分。
    2)可以同时进行开发:项目开发开始,首先制定前后端数据交互的借口文档(文档中包含了,调取哪个借口或者哪些数据等协议规范),后台把借口先写好(目前很多公司也需要前端自己拿node来模拟这些接口),客户端按照接口调取即可,后台再去实现接口功能即可。

【弊端】:

  • 不利于SEO优化:第一次从服务器端获取的内容不包含需要动态绑定的数据,所以页面的源代码中没有这些内容,不利于SEO收录,后期通过JS添加到页面中的内容,并不会写在页面的源代码中(是源代码不是页面结构)。
  • 交由客户端渲染,首先需要把页面呈现,然后再通过JS的异步AJAX请求获取数据,然后数据绑定,浏览器再把动态增加的部分重新渲染,无形中浪费了一些时间,没有服务器端渲染页面呈现速度快。

在这里插入图片描述

基于原生JS实现AJAX

//1、创建一个AJAX对象
var xmlhttp;
if (window.XMLHttpRequest) {
    //  IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码
    xmlhttp=new XMLHttpRequest();
}else{
    // IE6, IE5 浏览器执行代码
    xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}

//2、打开请求地址(可以理解为一些基础配置,但是并没有发送请求)
xmlhttp.open([mehtod],[url],[async],[username],[user password]);

//3、监听AJAX状态改变,获取响应信息(获取响应头信息、获取响应主体信息)
xmlhttp.onreadystatechange = ()=>{
    if(xhr.readyState === 4 && xmlhttp.status === 200){
        let result = xhr.responseText;  //获取响应主体中的内容

    }
}

//4、发送AJAX请求(括号中传递的内容就是请求主体的内容)
xmlhttp.send(null);

分析第二步中的细节知识点:

xmlhttp.open([mehtod],[url],[async],[username],[user password]); 

【AJAX请求方式】
1、GET系列的请求(获取)

  • get
  • delete:从服务器上删除某些资源文件
  • head:指向获取服务器返回的响应头信息(响应主体内容不需要获取)

2、POST系列的请求(推送)

  • post
  • put:向服务器中增加指定的资源文件

不管哪一种请求方式,客户端都可以把信息传递给服务器,服务器也可以把信息返回给客户端,只是GET系列一般以获取为主(给的少,拿回来的多),而POST系列一般系列一般以推送为主(给的多,拿回来的少)。
1)我们想获取一些动态展示的信息,一般使用GET请求,因为只需要向服务器端发送请求,告诉服务器端我们想要什么,服务器端就会把需要的数据返回。
2)在实现注册功能的时候,我们需要把客户输入的信息发送给服务器进行存储,服务器一般返回成功还是失败等状态,此时我们一般都是基于post请求完成的。

GET系列请求和POST系列请求,在项目实战中存在很多的区别:

1、GET请求传递给服务器的内容一般没有POST请求传递给服务器的内容多
原因:GET请求传递给服务器内容一般都是基于url地址问号传递参数来实现的,而POST请求一般都是基于设置请求主体来实现的。
各浏览器都有自己的关于url最大长度的限制(谷歌:8KB;火狐:7KB;IE:2KB…),超过限制长度的部分,浏览器会自动截取掉,导致传递给服务器的数据缺失。
理论上POST请求通过请求主体传递是没有大小限制的,真实项目中为了保证传输的速率,我们也会限制大小(例如:上传的资料或者图片我们会做大小的限制)。
2、GET请求很容易出现缓存(这个缓存不可控:一般我们都不需要),而POST不会出现缓存(除非自己做特殊处理)。
原因:GET是通过URL问号传递给服务器信息,而POST是设置请求主体。
设置请求主体不会出现缓存,但是URL传递参数就会了。

//每隔一分钟重新请求服务器最新的数据,然后展示在页面中(页面中某些数据实时刷新)
setTimeout(()=>{
	$.ajax({
		url: 'getList?lx=news',
		...
		success: result=>{
			//第一次请求数据回来,间隔一分钟后,浏览器又发送一次请求,但是新发送的请求,不管是地址还是传递的参数都和第一次一样,浏览器很有可能会把上一次数据获取,而不是获取最新的数据
		}
	});
},60000);

//=>解决方案:每一次重新请求的会后,在url的末尾追加一个随机数,保证每一次的请求地址不完全一致,就可以避免是从缓存中读取的数据
setTimeout(()=>{
	$.ajax({
		url: 'getList?lx=news&_='+Math.random(),
		...
		success: result=>{
			
		}
	});
},60000);

3、GET请求没有POST请求安全(POST也并不是十分安全,只是相对安全)
原因:还是因为GET是URL传递参数给服务器
有一种比较简单的黑客技术:URL劫持,也就是可以把客户端传递给服务器的数据劫持掉,导致信息泄露。

open方法中剩下的几个参数:

  • URL:请求数据的地址(API地址),真实项目中,后台开发工程师会编写一个API文档,在API文档中汇总了获取哪些数据需要使用哪些地址,我们按照文档操作即可。

  • ASYNC:异步(SYNC:同步),设置当前AJAX请求是异步的还是同步的,不写默认是异步(true),如果设置为false,则代表当前请求是同步的。

  • 用户名和密码:这两个参数一般不用,如果你请求的URL地址所在的服务器设定了访问权限,则需要我们提供可通行的用户名和密码才可以(一般服务器都是可以允许匿名访问的)。

第三步细节研究:

//3、监听AJAX状态改变,获取响应信息(获取响应头信息、获取响应主体信息)
xmlhttp.onreadystatechange = ()=>{
    if(xhr.readyState === 4 && xmlhttp.status === 200){
        let result = xhr.responseText;  //获取响应主体中的内容

    }
}

xmlhttp.readyState
AJAX状态码:描述当前AJAX操作的状态的。
0:UNSENT,未发送,只要创建一个AJAX对象,默认值就是0
1:OPENED,我们已经执行了xmlhttp.open这个操作
2:HEADERS_RECEIVED,当前AJAX的请求已经发送,并且已经接收到服务器返回的响应头信息了
3:LOADING,响应主体内容正在返回的路上
4:DONE,响应主体内容已经返回到客户端

xmlhttp.status
HTTP网络状态码:记录了当前服务器返回信息的状态。
常用的HTTP状态码:

  • 200:成功,一个完整的HTTP事务完成(以2开头的状态码一般都是成功)。

  • 以3开头的一般也是成功,只不过服务器端做了很多特殊的处理。
    301:Moved Permanently,永久转移(永久重定向),一般应用于域名迁移
    302:Moved temporarily,临时转移(临时重定向,新的HTTP版本中认为307才是临时重定向)。一般用于服务器的负载均衡:当前服务器处理不了,我把当前请求临时交给其他服务器处理(一般图片请求经常出现302,很多公司都有单独的图片服务器)。
    304:Not Modified,从浏览器缓存中获取数据。把一些不经常更新的文件或者内容缓存到浏览器中,下一次从缓存中获取,减轻服务器压力,也提高页面加载速度。

  • 以4开头的,一般都是失败,而且客户端的问题偏大。
    400:请求参数错误
    401:无权限访问
    404:访问地址不存在

以5开头的,一般都是失败,而且服务器的问题偏大。
500:Internal Server Error,未知的服务器错误
503:Service Unavailable,服务器超负载

AJAX中其他常用的属性和方法:
面试题:AJAX中总共支持几个方法?

let xmlhttp = new XMLHttpRequest();
console.dir(xmlhttp);

【常用属性】:

  • readyState:存储的是当前AJAX的状态码。
  • response、responseText、responseXML:都是用来接收服务器返回的响应主体中的内容,只是根据服务器返回内容的格式不一样,我们使用不同的属性接收即可。
  • responseText是最常用的,接收到的结果是字符串格式的(一般服务器返回的数据都是JSON格式字符串)
    responseXML偶尔会用到,如果服务器返回的是XML文档数据,我们需要使用这个属性接收。
  • status:记录了服务器端返回的HTTP状态码。
  • statusText:对返回状态码的描述。
  • timeout:设置当前AJAX请求的超时时间,假设我们设置时间为3000(ms),从AJAX请求发送开始,3s后响应主体还没有返回,浏览器会把当前AJAX请求任务强制断开。

【方法】:

  • abort():强制中断AJAX请求。
  • getAllResponseHeaders():获取全部的响应头信息(获取的结果是一堆字符串文本)。
  • getResponseHeader(key):获取指定属性名的响应头信息,例如:xmlhttp.getResponseHeader(‘date’),获取响应头中存储的服务器的时间。
  • open():打开一个URL地址。
  • overrideMimeType():重写数据的MIME类型。
  • send():发送AJAX请求(括号中书写的内容是客户端基于请求主体把信息传递给服务器)。
  • setRequestHeader(key, value):设置请求头信息(可以使设置的自定义请求头信息)。

【事件】:

  • onabort:当AJAX被中断请求触发这个事件。
  • onreadystatechange:AJAX状态发生改变,会触发这个事件。
  • ontimeout:当AJAX请求超时,会触发这个事件
    … …

JS中常用的编码解码方法

正常的编码解码(非加密)
1、escape、unescape:主要就是把中文汉字进行编码解码的(一般只有JS语言支持,所以经常用于前端页面通信时候的中文汉字编码)。
在这里插入图片描述
2、encodeURI、decodeURI:基本上所有的编程语言都支持。
在这里插入图片描述
3、encodeURIComponent、decodeURIComponent:和第2中方式非常相似,区别在于:
需求:我们URL问号传参的时候,我们传递的参数值还是一个URL或者包含很多特殊的字符,此时为了不影响主要的URL,我们需要把传递的参数值进行编码。使用encodeURI不能编码一些特殊字符,所以只能使用encodeURIComponent。
在这里插入图片描述在这里插入图片描述

也可以通过加密的方式进行编码解码
1、可逆转加密(一般都是团队自己玩的规则)。
2、不可逆转加密(一般都是基于MD5加密完成的,可能会把MD5加密后的结果二次加密)。

AJAX中的同步和异步

AJAX这个任务:发送请求+接收到响应主体内容(完成一个完整的HTTP事务)。
xhr.send():任务开始。
xhr.readyState===4:任务结束。

同步:
1、send()放在onreadystatechange事件监听后面:

let xhr = new XMLHttpRequest();
xhr.open('get', 'temp.json', false);
xhr.onreadystatechange = ()=>{
    console.log(xhr.readyState);    
}
xhr.send();
// 只输出一次,结果是4

在这里插入图片描述
2、send()放在前面执行

let xhr = new XMLHttpRequest();
xhr.open('get', 'temp.json', false);
xhr.send();
// 【同步】开始发送AJAX请求,开启AJAX任务,在任务没有完成之前,什么时都做不了(下面绑定事件也坐不了)
// LOADING => 当readyState === 4的时候AJAX任务完成,开始执行下面的操作
// readyState===4

xhr.onreadystatechange = ()=>{
    console.log(xhr.readyState);    
}
// 绑定方法之前状态已经为4了,此时AJAX的状态不会变成其他值了,
// 所以onreadystatechange事件永远不会被触发,一次都没执行方法
// 使用AJAX同步编程,不要把SEND放在事件监听前,这样我们无法在绑定的方法中获取到响应主体内容

// 没有输出结果
let xhr = new XMLHttpRequest();
// xhr.readyState===0
xhr.onreadystatechange = ()=>{
    console.log(xhr.readyState);
}
xhr.open('get', 'temp.json',false);
// xhr.readyState===1
// AJAX特殊处理的一件事:执行OPEN状态会变为1,会主动把之前监听的方法执行一次,然后再去执行send
xhr.send();
// xhr.readyState===4

// 输出 1 4

异步:

let xhr = new XMLHttpRequest();
xhr.open('get', 'temp.json');
// 这里的readyState===1
xhr.onreadystatechange = ()=>{
    console.log(xhr.readyState);    
}
xhr.send();
// => 2 3 4

在这里插入图片描述

let xhr = new XMLHttpRequest();
xhr.open('get', 'temp.json');
xhr.send();
// 这里的readyState===1
xhr.onreadystatechange = ()=>{
    console.log(xhr.readyState);    
}
// => 2 3 4
let xhr = new XMLHttpRequest();
// 这里的readyState===0
xhr.onreadystatechange = ()=>{
    console.log(xhr.readyState);    
}
xhr.open('get', 'temp.json');
xhr.send();
// => 1 2 3 4

AJAX类库的封装

JQ中的AJAX使用及每一个配置的作用:

$.ajax({
	url: 'xxx.txt',	//=>请求API地址
	method: 'get', //=>请求方式GET/POST...在老版本中JQ使用的是type,type和method实现的是相同的效果
	dataType: 'json', //=>dataType只是我们预设获取的结果类型,不会影响服务器的返回(服务器一般给我们返回的都是JSON格式字符串)。如果我们预设的是json,那么类库中将把服务器返回的字符串转换为json对象;如果我们预设的是text(默认值),我们把服务器获取的结果直接拿过来操作即可,我们预设的值还可以是xml等。
	cache: false, //=>设置是否清除缓存,只对GET系列请求有作用,默认是true不清缓存,手动设置为false,JQ类库会在请求url的末尾追加一个随机数来清除缓存。
	data: null, //=>我们通过data可以把一些信息传递给服务器:GET系列请求会把data汇总的内容拼接在url末尾通过问号传参的方式传递给服务器,post系列请求会把内容放在请求主体中传递给服务器。data的值可以设置为两种格式:字符串、对象,如果是字符串,设置的值是什么传递给服务器的就是什么,如果设置的是对象,JQ会把对象变为xxx=xxx&xxx=xxx这样的字符串传递给服务器。
	async: true, //=>设置同步或者异步,默认true为异步,设置为false为同步。
	sucess: function(result){
		//=>当AJAX请求成功(readyState===4 && status是以2或者3开头的)
		//=>请求成功后JQ会把传递的回调函数执行,并且把获取的结果当做实参传递给回调函数(result就是我们从服务器获取的结果)
	},
	error: function(msg){	//=>请求错误触发回调函数
	},
	complete: function(){	//=>不管请求是错误还是正确的都会触发回调函数(它是完成的意思)
	},
	...
});
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值