学向勤中得,萤窗万卷书。这篇文章主要讲述30 分钟,全面解析 AJAX #yyds干货盘点#相关的知识,希望能为你提供帮助。
阅读本文需要 30 分钟,请先收藏转发后再看。
先上原理图
文章图片
(另外这张图是我在博客园画的图,所以水印是博客园的,也欢迎大家关注我的博客园。)
背景
- 传统的 Web 网站,提交表单,需要重新加载整个页面。
- 如果服务器长时间未能返回 Response,则客户端将会无响应,用户体验很差。
- 服务端返回 Response 后,浏览器需要加载整个页面,对浏览器的负担也是很大的。
- 浏览器提交表单后,发送的数据量大,造成网络的性能问题。
- 如何改进?
- 有什么优势?
- 有什么缺点?
当需要从服务器获取数据,并刷新页面的操作,如果不采用 AJAX,则需要用提交整个表单的方式,当提交表单时,发送请求给服务器,页面需要等待服务器发送完 response 后,页面才能恢复操作。
1.2 AJAX 的概念
1.AJAX = 异步 javascript 和 XML。
2.AJAX 是一种用于创建快速动态网页的技术。
- 通过在后台与服务器进行少量数据交换,可以使网页实现异步更新。
- 可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
当前页面发送一个请求给服务器,当前页面不需要等待服务器响应才能操作网页。发送完请求之后,当前页面可以继续浏览,操作。
1.4 什么叫局部刷新
我们可以用两种方式来实现部分刷新。
(1) iframe 页面重载的方式。
这种方式虽然实现了部分刷新,但是是页面的重载,所以也会带来性能上的问题。
- Step1. 在页面中定义一个 Iframe
<
iframe id="indexFrame" name="index"
frameborder="0" margin margin scrolling="yes" style="margin-top:100px;
">
<
/iframe>
- Step2. 设置 iframe 的 src
var indexFrame = document.getElementById("indexFrame");
indexFrame.src = "https://www.songbingjia.com/android/introduction.php";
- Step3. 添加一个 button 的点击事件,当点击这个 button 时,重新设置 Iframe 的 src,实现 iframe 里面的页面刷新。iframe 外面的内容不刷新。
<
button id="room" onclick=IndexClick("room")>
Click Me!<
/button>
function IndexClick(moduleKey) {
var indexFrame = document.getElementById("indexFrame");
if(indexFrame == null)
{
indexFrame = parent.document.getElementById("indexFrame");
}
var url = "introduction.php";
switch (moduleKey) {
case "introduction":
url = "introduction.php";
break;
case "room":
url = "room.php";
break;
default:
{
}
}
indexFrame.src = https://www.songbingjia.com/android/url;
}
通过这种方式我们可以实现一个导航栏的功能:
文章图片
(2)AJAX 方式
Step1.javaScrpit 发送异步请求
Step2. 服务端查询数据库,返回数据
Step3. 服务端返回 Response
Step4. 客户端根据返回的 Response,来用 JavaScript 操作 DOM。
看下面的例子:
当我们切换 DropDownList 中的 Item 时,JavaScript 发送异步请求给 Server 端,Server 端返回数据,然后 JavaScript 将数据解析出来,拼接了一个 Table,将 Table 呈现在页面上。
二、提交 Form 表单的原理 2.1 代码
客户端代码:
<
form id="form1" action="Test.ashx" method="get">
您的姓名 1:<
input type="text" name="fname" size="20" />
<
input type="submit" name="submit" value="https://www.songbingjia.com/android/Sumbit">
<
/form>
服务端代码:
public void ProcessRequest (HttpContext context)
{
//Delay
for (int i = 0;
i <
2;
i++)
{
System.Threading.Thread.Sleep(1000);
}//从 Requset.Form 中获取 fname 的值。使用 Form 获取请求的键值对的值的前提条件是 HTTP request Content-Type 值必须是"application/x-www-form-urlencoded" 或 "multipart/form-data".
string fname = context.Request["fname"];
context.Response.ContentType = "text/plain";
//将字符串写入 HTTP 响应输出流。
context.Response.Write("Hello World " + fname);
}
2.2 将代码部署到 IIS
文章图片
2.3 打开站点:
http://localhost:8003/Test.html
文章图片
2.4 输入“Jackson0714”然后点击 Sumbit 按钮
页面会重新刷新,显示" Hello World Jackson0714"
【30 分钟,全面解析 AJAX #yyds干货盘点#】
文章图片
2.5 提交 Form 表单后,页面发送请求和服务端返回响应的流程
文章图片
2.6 通过抓包,我们可以得到 HTTP Headers
浏览器发送 HTTP 给服务端,采取的协议是 HTTP 协议。
在传输过程中,我们可以看下 HTTP Headers。
文章图片
三、AJAX 提交请求和服务响应的原理 3.1 代码
客户端 html 代码:
<
!DOCTYPE html>
<
html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<
head>
<
meta charset="utf-8" />
<
title>
<
/title>
<
script type="text/javascript" src="https://www.songbingjia.com/android/Ajax.js">
<
/script>
<
/head>
<
body>
<
div id="Test" style="background-color:#40eeee">
您的姓名 2:<
input type="text" id="testGetName" size="20" />
<
button type="button" onclick="testGet();
">
Ajax Get 请求<
/button>
<
/div>
<
div id="Test" style="background-color:#ff6a00">
您的姓名 3:<
input type="text" id="testPostName" size="20" />
<
button type="button" onclick="testPost();
">
Ajax Post 请求<
/button>
<
/div>
<
div id="myDiv" />
<
/body>
<
/html>
客户端 JS 代码:
var xmlhttp = createRequest();
function testGet() {
var fname = document.getElementById("testGetName").value;
xmlhttp.open("GET", "Test.ashx?fname=" + fname + "&
random=" + Math.random() , true);
xmlhttp.onreadystatechange = callback;
xmlhttp.send(null);
}function testPost() {
var fname = document.getElementById("testPostName").value;
xmlhttp.open("POST", "Test.ashx?"+ "&
random=" + Math.random() , true);
xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;
charset=UTF-8");
xmlhttp.onreadystatechange = callback;
xmlhttp.send("fname="+fname);
}function createRequest() {
var xmlhttp;
if (window.XMLHttpRequest) {
// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
}
else {
// code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
return xmlhttp
}function callback() {
if (xmlhttp.readyState == 4 &
&
xmlhttp.status == 200) {
document.getElementById("myDiv").innerHTML = xmlhttp.responseText;
}
}
这里有一点需要注意
var xmlhttp = createRequest(); 。
- 让服务端能够操作这个变量 xmlhttp ,如果定义成局部变量,则服务端返回 response 时,不能对 xmlhttp 的属性赋值。回调函数要求 request 是全局的,才能访问这个变量和它的属性值。
- 定义成全局变量后,可能出现两个请求或多个请求共享同一个请求对象。而这个请求对象只能存放一个回调函数来处理服务器响应。当服务器返回两个请求的 Response 后,可能会调用后指定的回调函数。所以可能有两个完全不同的服务器响应由同一个回调函数处理,而这可能并不是正确的处理。解决办法是创建两个不同的请求对象。
3.2 输入“Jackson0714”然后点击 Sumbit 按钮
页面不会刷新,在最下面显示" Hello World Jackson0714"
文章图片
3.3 AJAX 发送请求和服务端返回响应的流程
文章图片
3.4 通过抓包,我们可以得到 HTTP Headers
浏览器发送 HTTP 给服务端,采取的协议是 HTTP 协议。
在传输过程中,我们可以看下 HTTP Headers:
文章图片
3.5 AJAXGET 和 POST 方式区别
AJAX 发送请求和 POST 发送请求的代码如下:
//GET 方式
function testGet() {
var fname = document.getElementById("testGetName").value;
xmlhttp.open("GET", "Test.ashx?fname=" + fname + "&
random=" + Math.random() , true);
xmlhttp.onreadystatechange = callback;
xmlhttp.send(null);
}//POST 方式
function testPost() {
var fname = document.getElementById("testPostName").value;
xmlhttp.open("POST", "Test.ashx?"+ "&
random=" + Math.random() , true);
xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;
charset=UTF-8");
xmlhttp.onreadystatechange = callback;
xmlhttp.send("fname="+fname);
}
- 请求的 URL 中,POST 方式可以添加键值对,也可以不添加
3.POST 可以用 send 方法发送额外信息。发送的信息存放在 content 中
4.Post 方式需要指定 Request Header 的类型。Get 方式不需要指定。
5.GET 方式将参数暴露在 URL 中,POST 不暴露。
四、XMLHttpRequest 对象的知识 4.1 XMLHttpRequest 对象的方法
文章图片
4.2 XMLHttpRequest 对象的属性
文章图片
五、JQuery 实现 AJAX下面的代码实现了当切换 DropDownList 的 item 时,触发 getWeeklyCalendar 方法,用 JQuery 的类库方法$.ajax 来发送 AJAX 请求。
客户端 JQuery 代码
function getWeeklyCalendar(name,currentDate,mode){
$.ajax({
type:POST,
url:weekProcess.php,data:func=getWeeklyCalender&
name=+name+&
currentDate=+currentDate+&
mode=+mode,
success:function(data){
paintWeeklyCandler(data);
}
});
}
后台成功返回 Response 后,执行 paintWeeklyCandler(data) 方法
后台 PHP 代码
<
?php//定义返回的 Response 的格式为 JSON 格式
header(Content-type: text/json);
<
br>
//引入自定义的数据库连接文件
include dbConfig.php;
<
br>
//引入自定义的设置 session 的文件
include_once session.php;
/*
* Function requested by Ajax
*/
if(isset($_POST[func]) &
&
!empty($_POST[func]))
{
switch($_POST[func]){
case getWeeklyCalender:
getWeeklyCalender($_POST[name],$_POST[currentDate],$_POST[mode]);
break;
case getWeeklyStatus:
getWeeklyStatus($_POST[name],$_POST[currentDate],$_POST[mode]);
break;
case getEvents:
getEvents($_POST[date],$_POST[name]);
break;
default:
break;
}
}function getWeeklyCalender($name = ,$currentDate = ,$mode = )
{
//逻辑代码<
br>
<
br>
<
br>
//返回 JSON 格式的 Response
echo json_encode(array(result=>
$DaysOfWeekResultsArray));
}
六、优势
- 使用异步方式与服务器通信,页面不需要重新加载,页面无刷新
- 按需取数据,减少服务器的负担
- 使得 Web 应用程序更为迅捷地响应用户交互
- 浏览器的内容和服务端代码进行分离。页面的内容全部由 JAVAScript 来控制,服务端负责逻辑的校验和从数据库中拿数据。
- 安全问题:将服务端的方法暴露出来,黑客可利用这一点进行攻击
- 大量 JS 代码,容易出错
- 可能破坏浏览器后退按钮的正常行为;
- 一些手持设备(如手机、PAD 等)自带的浏览器现在还不能很好的支持 Ajax
- 对数据进行过滤和操纵相关数据的场景
- 添加/删除树节点
- 添加/删除列表中的某一行记录
- 切换下拉列表 item
- 注册用户名重名的校验
- 整个页面内容的保存
- 导航
《ASP.NET 4 高级程序设计》
《Head First AJAX》
AJAX 工作原理及其优缺点
https://msdn.microsoft.com/zh-cn/library/1463ysyw(v=vs.110).aspx
https://msdn.microsoft.com/en-us/library/system.web.httprequest.form.aspx
https://msdn.microsoft.com/zh-cn/library/system.web.httpcontext.request(v=vs.80).aspx
https://msdn.microsoft.com/zh-cn/library/system.web.httpcontext.response(v=vs.110).aspx
推荐阅读
- 算法 | 第1章 数组与字符串相关《程序员面试金典》#yyds干货盘点#
- 彻底搞懂HTTP协议 - 天天造轮子
- #yyds干货盘点#探索 CSS Paint API(多边形边框)
- JAVA方法的定义
- JAVA递归算法
- #私藏项目实操分享#Alibaba中间件技术系列「Sentinel技术专题」分布式系统的流量防卫兵的基本介绍(入门源码介绍)
- EasyNVR近期功能点优化及问题更新调整
- #yyds干货盘点#捌哥图解栈帧,彻底告别面试死记硬背
- JAVA自增自减运算符,i++,++i