ajax和form都可以向服务器发送请求,但是form同一时间,只能处理一个任务,会影响效率。ajax可以异步处理任务。form可以自动收集数据,然后发送给服务器,但是ajax需要手动收集数据,然后发送给服务器。
一.HTTP协议
1. 请求头
Host:要访问的主机
Connection: keep-alive,客户端告诉服务器开启持久连接
User-Agent: 告诉服务器,浏览器的类型和版本号
Accept-Language:zh-CN, 浏览器可以接收的语言类型
Accept-Encoding: gzip, deflate,浏览器可以接收的压缩文件的格式
Referer: 二级页面才有这个属性,表示这个二级页面来源于哪个页面
2. 响应
2.1 响应状态码
(1)1xx:正在处理请求
(2)2xx:响应成功
(3)3xx:重定向
301永久重定向
302临时重定向
304请求未改变,命中缓存
(4)4xx:客户端错误
404请求资源不存在
403权限不够
405请求方法不被允许
(5)5xx:服务端错误
2.2 响应头
(1)Date:服务器响应时间
(2)Connection:告诉浏览器,服务器打开了持久连接
(3)Content-Type:告诉浏览器,响应主题的类型是什么
1. text/html html文本
2. text/css css文本
3. application/javascript js脚本文件
4. application/xml xml文件
5. application/json json文件
6. image/gif gif图片文件
7. image/png png图片文件
8. image/jpg jpg图片文件
3. 缓存
客户端将服务器响应的数据自动缓存,当再次请求时,将使用缓存的数据,而不需要再次向服务器请求。
在request header中有一个设置:
Cache-Control: max-age=0 单位是s
从服务器将文档传输到客户端时,此文档处于新鲜的秒数,是一个相对时间。如果是0,表示不缓存,如果是3600,则表示缓存1小时
<head>
<meta http-equiv="Cache-control" content="max-age=3600"
</head>
二.DOM操作
为什么要dom操作?因为form表单提交数据时,会自动收集整理数据,然后发送给服务器;但是ajax需要手动收集数据,然后发送给服务器,这个搜集数据的过程需要分成两步:
1. 找到元素对象
2. 获取这个对象的value
javascript主要由三部分组成:
1. js核心代码:ECMA Script, ES6
2. DOM:文档对象模型,就是为了操作html中的元素(内容,值,样式)
3. BOM:浏览器对象模型,让js可以动态的操作浏览器
1. 使用JS的dom操作页面数据
1.1 获取元素对象
var obj = document.getElementById("元素ID");
该方法对于任何的标签(不管是单标签还是双标签)都是有效的
1.2 获取/修改元素的值
(1)对于input标签
获取值:var val = obj_input.value
修改值:obj_input.value = xxx
(2)对于双标签元素
获取值:var htmlVal = obj.innerHTML
修改值:obj.innerHTML = xxx
(3) 简写形式
ES6中可以直接将元素的id属性作为对象使用
<html>
<head>
<title>dom测试</title>
<meta charset="utf-8"/>
<script>
function show() {
d2.innerHTML = d1.value;
}
</script>
</head>
<body>
<div>
输入框1:<input type="text" id="d1">
</div>
<p id="d2"></p>
<button onclick="show()">测试按钮</button>
</body>
</html>
1.3 练习
创建两个input框,点击按钮时将input1中的value显示在input2中
<!DOCTYPE html>
<html>
<head>
<title>dom测试</title>
<meta charset="utf-8"/>
<script>
function show() {
var input1 = document.getElementById("d1");
var input2 = document.getElementById("d2");
input2.value = input1.value;
}
</script>
</head>
<body>
<div>
输入框1:<input type="text" id="d1">
</div>
<div>
输入框2:<input type="text" id="d2">
</div>
<button onclick="show()">测试按钮</button>
</body>
</html>
1.4 innerHTML
动态添加表格
<html>
<head>
<title>dom测试</title>
<meta charset="utf-8"/>
<script>
function append() {
table_body.innerHTML += `
<tr>
<td>${loginname.value}</td>
<td>${email.value}</td>
<td>${phont.value}</td>
<td>${uname.value}</td>
<td>${sex.value}</td>
<td><a href="#">${op.value}</a></td>
</tr>
`;
loginname.value = '';
email.value = '';
phont.value = '';
uname.value = '';
sex.value = '';
op.value = '';
}
</script>
</head>
<body>
<div id="table_div">
<table border="1px">
<tr>
<th>登录名称</th>
<th>电子邮箱</th>
<th>联系方式</th>
<th>用户名称</th>
<th>用户性别</th>
<th>操作</th>
</tr>
<tbody id="table_body">
</tbody>
</table>
</div>
<br/>
<div>
登录名称: <input type="text" id="loginname"><br/>
电子邮箱: <input type="text" id="email"><br/>
联系方式: <input type="text" id="phont"><br/>
用户名称: <input type="text" id="uname"><br/>
用户性别: <input type="text" id="sex"><br/>
操作 : <input type="text" id="op"><br/>
</div>
<button onclick="append()">录入信息</button>
</body>
</html>
1.5 事件
通过用户的行为来激发的操作就是事件。
onclick 单击事件
onblur 焦点移除事件,元素失去焦点调用对应的js
onfocus 获取焦点事件,元素获得焦点,调用js
<html>
<head>
<meta charset="utf-8">
<script>
function blurMsg() {
msg.innerHTML = "请提交用户信息";
}
function focusMsg() {
msg.innerHTML = "请输入用户信息";
}
</script>
</head>
<body>
<input type="text" onblur="blurMsg()" onfocus="focusMsg()">
<span id="msg"></span>
</body>
</html>
三.ajax
1. 同步/异步
(1)同步
在一个任务执行时,不能开启其他任务。
同步访问:浏览器在向服务器发送请求,只能等待服务器的响应,不能做其他事情。
出现场合:
1. 地址栏输入url访问页面
2. a标签的跳转
3. form表单的提交
(2)异步
在一个任务执行时,可以同时进行其他任务。
出现场合:
1. 用户名注册的验证
2. 百度搜索建议
3. 股票软件
2. Ajax
全称:async javascript and xml
本质:使用js提供的异步对象XMLHttpRequest,简称xhr
ajax异步的发送请求给服务器,并接收服务器返回的结果
2.1 使用ajax四部曲
1. 创建异步对象
var xhr = new XMLHttpRequest();
2. 创建请求
xhr.open(method, url, isAsync);
xhr.open("get", "http://127.0.0.1:8080/login", true);
3. 发送请求
xhr.send(formdata); get请求使用null,或者不写参数
4. 绑定监听,接收响应数据
xhr.onreadystatechange = function(){}
2.2 xhr
1. xhr.readyState属性
用于表示xhr对象的请求状态,一共有5个状态
0:表示请求尚未初始化
1:表示已经打开服务器连接,正在发送请求
2:已经开始接收响应头
3. 已经开始接收响应主体
4. 响应数据接收完毕
2. onreadystatechange方法属于回调方法,当readyState发生变动时就会触发(0 -> 1, 1 -> 2 ...),通常我们只监听3 -> 4时候的变动,也就是响应数据接收完毕时进行处理。
而且由于send是异步过程,为了能够监听到所有的change,应当将监听回调函数的定义放在send方法之前。
2.3 示例
<html>
<head>
<title>ajax测试</title>
<meta charset="UTF-8">
<script>
function show() {
//1.创建异步对象
var xhr = new XMLHttpRequest();
//4. 绑定监听,接收响应
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) { //表示响应数据接收完毕,且返回结果正常
var result = xhr.responseText;
}
}
//2.打开连接,创建请求
xhr.open("get", "http://127.0.0.1:8080/login", true);
//3. 发送请求
xhr.send();
}
</script>
</head>
<body>
<button onclick="show()">ajax</button>
</body>
</html>
2.4 传参
1. get传参
客户端:
let url = `/user/login?uname=${uname.value}&upwd=${upwd.value}`;
服务器:
[req.query.uname, req.query.upwd]
2. 路径传参
客户端:
let url = `/user/loginRestful/${uname.value}/${upwd.value}`;
服务器:
router.get('/loginRestful/:uname/:upwd', (req, res) => {
pool.query('select * from john_user where uname = ? and upwd = ?',
[req.params.uname, req.params.upwd],
(err, result) => {
if(err) throw err;
res.send(result);
});
});
3. post传参
客户端:
function login() {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
var result = xhr.responseText;
alert(result);
}
};
xhr.open('post', '/user/login_post', true);
let formdata = `uname=${uname.value}&upwd=${upwd.value}`;
//由于包含特殊字符,需要修改请求头
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send(formdata);
}
服务器:
router.post('/login_post', (req, res) => {
pool.query('select * from john_user where uname = ? and upwd = ?',
[req.body.uname, req.body.upwd],
(err, result) => {
if(err) throw err;
res.send(result);
});
});
2.5 json
服务器返回给客户端的默认是json格式的字符串。JSON.parse(str)
客户端
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户列表</title>
<script>
function list() {
let xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if(xhr.readyState === 4 && xhr.status === 200){
let result = xhr.responseText;
//string -> 数组对象
let arr = JSON.parse(result);
for(u in arr){
users.innerHTML += `
<tr>
<td>${arr[u].uname}</td>
<td>${arr[u].upwd}</td>
<td>${arr[u].phone}</td>
<td>${arr[u].email}</td>
</tr>
`;
}
}
};
xhr.open('get', '/user/list', true);
xhr.send();
}
</script>
</head>
<body>
<h2>用户列表</h2>
<div id="userlist">
<table border="2px">
<tr>
<th>用户名</th>
<th>密码</th>
<th>电话</th>
<th>邮箱</th>
</tr>
<tbody id="users"></tbody>
</table>
</div>
<button onclick="list()">查询</button>
</body>
</html>
服务器:
router.get('/list', (req, res) => {
pool.query('select * from john_user ',
(err, result) => {
if(err) throw err;
res.send(result);
});
});
3. 项目
3.1 body的加载事件
<body onload="list()">...</body>
3.2 BOM操作
//页面跳转
location.href="xxxx";
//地址栏参数解析
let urlParams = new URLSearchParams(location.search);
let id = urlParams.get("id");