Ajax技术概述
Posted 橘猫吃不胖~
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Ajax技术概述相关的知识,希望对你有一定的参考价值。
Ajax技术概述
1 初识Ajax
在传统网站中,网页无法实现局部更新,当用户刷新页面时,整个页面的数据都会更新,在网速慢的情况下,如果网页非常大,用户体验就会非常不好。为了提高用户的体验,Ajax实现了网页局部的更新。
1.1 传统网站中存在的问题
Ajax(Asynchronous javascript and XML,异步JavaScript和XML)是一种网页开发技术,它可以实现页面无刷新更新数据,提高用户浏览网页的体验。
传统网站引起用户体验不好的地方:
- 无法局部刷新页面。传统网站中,当页面发生跳转时,需要重新加载整个页面。但是,一个网站中大部分网页的公共部分(头部、底部和侧边栏)都是一样的,没必要重新加载,反而延长了用户的等待时间。
- 页面加载的时间长。用户只能通过刷新页面来获取服务器端的数据,若数据量大、网速慢,用户等待的时间会很长
- 表单提交的问题。用户提交表单时,如果用户在表单中填写的内容有一项不符合要求,网页就会重新跳转回表单页面。由于页面发生了跳转,用户刚刚填写的信息都消失了,因此需要重新填写。尤其当填写的信息比较多时,每次失败都要重新填写,用户体验很差。
1.2 Ajax的工作原理
传统网站从浏览器端向服务器端发送请求的工作原理:
Ajax网站从浏览器端向服务器端发送请求的工作原理:
1.3 同步处理与异步处理
同步处理:客户端向服务器端发送请求,然后等待服务器端响应后再进行后续的操作
异步处理:客户端向服务器端发送请求后不等待服务器端的响应,继续进行后续操作;当服务器端响应后,客户端会调用相应的回调函数进行处理。
1.4 XMLHttpRequest对象
Ajax技术的核心:XMLHttpRequest对象。该对象不是w3c的标准对象,因此在使用XMLHttpRequest对象发生请求和处理之前,需要先在JavaScript代码中获取该对象。
获取XMLHttpRequest对象,需要判断浏览器的类型,示例代码如下:
let xmlhttpRequest;
if (window.ActiveXObject) // 表示浏览器是早期的IE浏览器
xmlhttpRequest = new ActiveXObject("Microsoft.XMLHTTP");
else if (window.XMLHttpRequest) //表示是符合w3c标准的浏览器
xmlhttpRequest = new XMLHttpRequest();
XMLHttpRequest方法如下所示:
方法 | 描述 |
---|---|
open(”method”,”URL”) | 建立对服务器的调用,method通常是post或get,URL为绝对路径或相对路径 |
abort() | 停止当前请求 |
getAllResponseHeaders() | 将所有HTTP请求的响应首部作为键/值对返回 |
getResponseHeader(”header”) | 返回指定响应的首部信息 |
send(content) | 向服务器发送请求,参数可以是null |
setRequestHeader(”header”, ”value”) | 设置HTTP请求的首部信息,可以向服务器传递参数,这个方法必须在open之后调用 |
XMLHttpRequest属性如下:
属性 | 描述 |
---|---|
Onreadystatechange | 每次请求—响应状态改变所触发的回调函数 |
readyState | 请求—响应的状态。 0 = 未初始化(uninitialized) 1 = 正在加载(loading) 2 = 加载完毕(loaded) 3 = 交互(interactive) 4 = 完成(complete) |
responseText | 从服务器进程返回的数据(字符串形式) |
responseXML | 从服务器进程返回的DOM兼容的文档数据对象 |
status | 从服务器返回的数字代码,如404(未找到)或200(就绪) |
statusText | 伴随状态码的字符串信息 |
2 Ajax基本实现步骤
Ajax的基本实现步骤:
- 创建服务器
- 配置Ajax对象
- 发送请求
2.1 创建服务器
示例:创建服务器,定义“/first”路由。使用WebStorm在文件夹中新建Express项目,命名为Ajax-demo,在routes文件夹下创建文件home.js,代码如下
const express = require("express");
const router = express.Router();
// 创建路由,http://localhost:3000/home/first
router.get("/first", (req, res) =>
res.send("Hello Ajax!");
)
// 导出路由模块
module.exports = router;
完成home.js文件后,还需要配置app.js文件,首先在第9行编写代码,引入路由文件:
var homeRouter = require('./routes/home');
然后在第25行代码中使用路由文件:
app.use('/home', homeRouter);
启动服务器,在浏览器中输入http://localhost:3000/home/first,成功显示Hello Ajax!,说明浏览器接口没有问题。
2.2 配置Ajax对象
首先创建Ajax对象,然后使用open()方法来配置Ajax对象,最后使用send()方法发送请求:
var xhr = new XMLHttpRequest();
xhr.open('请求方式', '请求地址');
xhr.send();
2.3 获取服务器端的响应
1、onload事件:通过onload事件的方式获取服务器端响应到客户端的数据。xhr表示Ajax对象,onload属性的值为事件处理函数。
xhr.onload = function () ;
2、onreadystatechange事件:通过onreadystatechange事件的方式获取服务器端响应到客户端的数据。
xhr.onreadystatechange = function () ;
xhr表示Ajax对象,onreadystatechange属性的值是事件处理函数。
Ajax状态码说明:
状态码 | 说明 |
---|---|
0 | 请求未初始化(还没有调用open()方法) |
1 | 请求已经建立,但是还没有发送(还没有使用send方法) |
2 | 请求已经发送 |
3 | 请求正在处理中,通常响应中已经有部分数据可以用了 |
4 | 响应已经完成,可以获取并使用服务器的响应了 |
示例:获取服务器端的响应。在Ajax-demo的public目录下新建index.html文件,编写JavaScript代码如下
<script>
// 创建Ajax对象
var xhr = new XMLHttpRequest();
// 获取Ajax状态码:0,代表请求未初始化
console.log("请求前状态码:", xhr.readyState);
// 配置Ajax对象,请求地址为上面创建服务器时创建的路由
xhr.open("get", "http://localhost:3000/home/first");
// 获取Ajax状态码:1,代表请求已经建立
console.log("请求后状态码:", xhr.readyState);
xhr.onload = function ()
// 获取Ajax状态码:4,表示响应已经完成
console.log("发送请求后状态码:", xhr.readyState);
// 获取服务器响应的数据:Hello Ajax!
console.log("服务器响应的数据:", xhr.responseText);
xhr.send(); // 向服务器端发送请求
</script>
启动服务器,在浏览器中打开index.html页面,打开开发者工具,显示以下信息
示例:将onload事件修改为onreadystatechange事件,获取服务器端的响应
<script>
// 创建Ajax对象
var xhr = new XMLHttpRequest();
// 配置Ajax对象,请求地址为上面创建服务器时创建的路由
xhr.open("get", "http://localhost:3000/home/first");
xhr.onreadystatechange = function ()
// 获取Ajax状态码2,3,4
console.log(xhr.readyState);
// 对Ajax状态码进行判断,如果状态码的值为4,表示数据已经接收完成了
if (xhr.readyState == 4)
console.log(xhr.responseText); // 输出Hello Ajax!
// 发送请求
xhr.send();
</script>
启动服务器,在浏览器中打开index.html页面,打开开发者工具查看终端中的信息如下:
注意:运行服务器后,在浏览器中打开index.html,会出现以下的问题,该问题就是跨域的问题
如果使用HTML文件直接访问时并不存在跨域问题,但如果通过JavaScript代码向远程服务器发送请求时,由于端口号和地址不相同,就会产生跨域问题。解决该问题请点击:WebStorm创建的Express项目解决跨域问题(cors方式)
3 请求参数
3.1 GET请求参数的传递
设置open()方法中的第1个参数为“get”,表示设置get请求方式。
xhr.open('get', 'http://localhost:3000/demo.html?username=zhangsan &age=20');
xhr.send();
“?”后面的“username=zhangsan&age=20”表示GET请求参数,多个参数时需要使用“&”符号连接
示例:在输入框中获取GET请求参数
第一步:编写index.html文件
用户名:<input type="text" id="username">
<br><br>
密码:<input type="password" id="password">
<br><br>
<button id="btn">登录</button>
<script>
// 获取用户名文本框的值
let username = document.getElementById("username");
// 获取密码文本框的值
let password = document.getElementById("password");
// 获取按钮元素
let btn = document.getElementById("btn");
// 为按钮注册点击事件
btn.onclick = function ()
// 获取用户在文本框中输入的值
username = username.value;
password = password.value;
// 拼接参数
let params = "username=" + username + "&password=" + password;
// 创建Ajax对象
let xhr = new XMLHttpRequest();
// 配置Ajax对象,这里3000后面的/get在后端代码会进行创建
xhr.open("get", "http://localhost:3000/get?" + params);
// 为Ajax对象注册onload事件
xhr.onload = function ()
// 获取从服务器中返回的数据(字符串形式)
console.log(xhr.responseText);
// 发送Ajax请求
xhr.send();
</script>
第二步:创建get.js文件,定义路由地址为:/get
const express = require("express");
const app = express();
// 解决跨域问题
const cors = require("cors");
app.use(cors());
// 创建路由
app.get("/get", (req, res) =>
res.send(req.query);
)
// 监听3000端口
app.listen(3000);
第三步:启动服务器,在浏览器中打开index.html文件,输入用户名和密码,查看终端显示的信息
3.2 POST请求参数的传递
请求消息是在HTTP请求和响应的过程中传递的数据块。
设置open()方法中的第1个参数为“post”表示设置POST请求方式。
xhr.open('post', 'http://localhost:3000/demo.html');
xhr.setRequestHeader(属性名, 属性值);
xhr.send(请求参数);
POST请求参数的传递会将请求参数放在了send()方法中,xhr.setRequestHeader()方法设置请求参数的类型。
Ajax对象中的setRequestHeader()方法用来设置请求消息中请求头信息。
xhr.setRequestHeader('Content-Type', '请求参数格式');
application/x-www-form-urlencoded请求参数的格式是用“&”符号连接多个“参数名称等于参数值”形式的数据,如“name=zhangsan&age=20&sex=nan”。
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
application/json请求参数的格式是JSON数据,如“name: ‘张三’, age: ‘20’, sex: ‘男’”,如果有多个参数时需要使用“,”符号连接。
xhr.setRequestHeader('Content-Type', 'application/json');
示例:POST请求参数的传递,实现"application/x-www-form-urlencoded"类型参数的传递
第一步:编写index.html文件,代码如下:
用户名:<input type="text" id="username">
<br><br>
密码:<input type="password" id="password">
<br><br>
<button id="btn">登录</button>
<script>
// 获取用户名文本框的值
let username = document.getElementById("username");
// 获取密码文本框的值
let password = document.getElementById("password");
// 获取按钮元素
let btn = document.getElementById("btn");
// 为按钮注册点击事件
btn.onclick = function ()
// 获取用户在文本框中输入的值
username = username.value;
password = password.value;
// 拼接参数
let params = "username=" + username + "&password=" + password;
// 创建Ajax对象
let xhr = new XMLHttpRequest();
// 配置Ajax对象,这里3000后面的/post在后端代码会进行创建
xhr.open("post", "http://localhost:3000/post?" + params);
// 设置请求参数格式的类型
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
// 为Ajax对象注册onload事件
xhr.onload = function ()
// 获取从服务器中返回的数据(字符串形式)
console.log(xhr.responseText);
// 发送Ajax请求
xhr.send(params);
</script>
第二步:使用第三方模块body-parser来处理POST请求参数。下载body-parser模块,执行命令如下
npm install body-parser@1.18.3 --save
body-parser模块可以用来解析JSON格式、URL-encoded格式的请求体,如JSON数据和表单数据。
第三步:新建port.js文件,定义路由地址“/post”
const express = require("express");
const bodyParser = require("body-parser");
const app = express();
// 解决跨域问题
const cors = require("cors");
app.use(cors());
app.use(bodyParser.urlencoded( extended: false ));
// 创建路由
app.post("/post", (req, res) =>
res.send(req.body);
)
// 监听3000端口
app.listen(3000);
第四步:启动服务器,在浏览器中打开index.html页面,输入用户名和密码,然后登录,在终端就会显示请求参数
示例:在index.html修改上述示例的第一步,实现“application/json”类型参数的传递,具体代码如下
btn.onclick = function ()
// 获取用户在文本框中输入的值
username = username.value;
password = password.value;
// 定义params对象
let params = ;
params["username"] = username;
params["password"] = password;
// 创建Ajax对象
let xhr = new XMLHttpRequest();
// 配置Ajax对象,这里3000后面的/post在后端代码会进行创建
xhr.open("post", "http://localhost:3000/post");
// 设置请求参数格式的类型
xhr.setRequestHeader("Content-Type", "application/json");
// 为Ajax对象注册onload事件
xhr.onload = function ()
// 获取从服务器中返回的数据(字符串形式)
console.log(JSON.parse(xhr.responseText));
// 发送Ajax请求
xhr.send(JSON.stringify(params));
在post.js文件第7行代码,使用bodyParser.json()解析“application/json”,具体代码如下:
app.use(bodyParser.json());
启动服务器,在浏览器打开index.html文件,程序运行结果与上一个示例相同。
3.3 案例演示
【案例说明】输入用户名和密码,在后台判断输入的用户名是否为“张三”,密码是否为“123456”,如果用户名输入错误,在输入框后提示“用户名错误”,如果密码输入错误,在输入框后提示“密码错误”,如果全部输入正确,则在登录按钮下方显示“合法用户”。
效果如下:
第一步:编写index.html页面,代码如下:
用户名:<input type="text" id="username">
<span id="user"></span>
<br><br>
密码:<input type="password" id="password">
<span id="pwd"></span>
<br><br>
<button id="btn">登录</button>
<h2 id="ok"></h2>
<script>
// 获取按钮
let btn = document.getElementById("btn");
// 给按钮注册click事件
btn.addEventListener("click", function ()
// 获取用户名和密码文本框的值
let username = document.getElementById("username").value;
let password = document.getElementById("password").value;
// 拼接参数
let params = "username=" + username + "&password=" + password;
// 创建Ajax对象
let xhr = new XMLHttpRequest();
// 配置Ajax对象
xhr.open("get", "http://localhost:3000/login/check?" + params);
// 定义状态改变时的回调函数
xhr.onreadystatechange = function ()
<以上是关于Ajax技术概述的主要内容,如果未能解决你的问题,请参考以下文章