服务器的基本概念与初识Ajax
一.客户端与服务器
定义
服务器:负责存放和对外提供资源的电脑,叫做服务器。
客户端:在因特网中负责获取和消费资源的电脑,通过浏览器
二.URL地址
1.URL地址的概念
URL中文名字叫统一资源定位符,用于标识互联网上每一个资源的唯一存放位置。浏览器只有通过URL地址,才能正确定位资源的存放位置,从而成功的访问到对应的资源。
2.URL地址的组成部分
URL地址一般由三部分组成:
1.客户端与服务器之间的通信协议
2.存有该资源的服务器名称
3.资源在服务器上具体存放位置
三.分析网页打开过程
1.概述
(客户端)打开浏览器=>(客户端)输入访问的网址=>(客户端)回车向服务器发送请求=>服务器接收客户端发来的资源请求=>服务器在内部处理这次请求,找到相关资源=>服务器把找到的资源,响应给客户端
注意
1.客户端和服务器之间的通信过程,分为请求-处理-响应三个步骤。
2.网页中的每一个资源都是通过请求-处理-响应的方式从服务器中获取回来的。
2.基于浏览器的开发者工具分析通讯过程
F12键进入
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ws6GMCta-1676954581192)(C:\Users\t-y-x\AppData\Roaming\Typora\typora-user-images\image-20230205143535812.png)]
四.服务器对外提供了那些资源
1.列举网页中常见的资源
文字内容、img图片、Audio音频、Video视频、网页中的数据也是服务器对外提供的一种资源。数据是网页的基础!
2.网页中如何请求数据
客户端发起请求=>服务器处理这次数据请求=>服务器把数据相应给客户端(也是基于请求 处理 响应)
如果在网页中请求服务器的数据资源,则需要XMLHttpRequest对象(简称xhr)。是浏览器提供的js成员,通过他可以请求服务器上的数据资料。
var xhr = new XMLHttpRequest();
3.资源请求方式
get请求:从服务器获取资源。例如根据url地址从服务器中获取HTML文件,css文件,js文件,图片文件,数据资源等。
post请求:向服务器提交数据(往服务器发送资源)。例如登入时向服务器提交登录信息,注册时向服务器提交注册信息,添加用户时向服务器提交用户信息等各种的数据提交操作。
五.了解Ajax
1.定义
Ajax的全称是:Asynchronous Javascript And XML(异步JavaScript和XML),通俗的理解就是:在网页中利用XMLHttpRequest对象和服务器进行数据交互的方式,叫Ajax!Ajax实现了网页与服务器之间数据的交互!!
2.Ajax的典型应用场景
用户名检测,检查用户名是否冲突(与数据库中的名字一样)
搜索提示,搜索关键字的后面名提示
数据的分页显示
数据的增删改查操作
六.jQuery中的Ajax
1.概述
浏览器提供的XMLHttpRequest用法比较复杂,所以jQuery对XMLHttpRequest进行了封装,解决了浏览器的兼容性问题,提供了一系列Ajax相关函数,极大地降低了Ajax的使用难度!
$.get(url, [data携带参数], [callback回调函数]); //获取数据
$.post(); //提交数据
$.ajax(); //既可以获取数据也可以提交数据
2.$.get()函数
专门发送get请求,从而服务器上的资源请求到客户端来进行使用。
$.get(url, [data携带参数], [callback回调函数])
url:string类型,要请求的地址,必填项
data:object对象类型,请求资源期间要携带的参数,选填项
callback:function函数类型,请求成功后的回调函数,选填项
发起不带参数的请求
直接提供URL地址和请求成功之后的回调函数即可
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="../lib/jquery.min.js"></script>
</head>
<body>
<button id="btnGet">发起不带参数的get请求</button>
<script>
$(function() {
$('#btnGet').on('click', function() {
$.get('http://www.liulongbin.top:3006/api/getbooks', function(res) {
console.log(res);//这里的res是服务器返回的数据
})
})
})
</script>
</body>
</html>
发起带参数的请求
在第二个参数下,传递一个参数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>发起带参数的请求</title>
<script src="../lib/jquery.min.js"></script>
</head>
<body>
<button id="btnGetInfo">发起带参数get的请求 </button>
<script>
$(function() {
$('#btnGetInfo').on('click', function() {
$.get('http://www.liulongbin.top:3006/api/getbooks', {
id: 1
}, function(res) {
console.log(res);
})
})
})
</script>
</body>
</html>
3.$.post()函数
jQuery中$.post()函数功能单一,专门用来发起post请求,从而向服务器提交数据!
$.post(url, [data携带参数], [callback回调函数])
url:string类型,提交数据的地址,必填项
data:object对象类型,要提交的数据,选填项
callback:function函数类型,数据提交成功后的回调函数,选填项
向服务器提交数据
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>向服务器提交数据</title>
<script src="../lib/jquery.min.js"></script>
</head>
<body>
<button id="btnPost">发起POST请求</button>
<script>
$(function() {
$('#btnPost').on('click', function() {
$.post('http://www.liulongbin.top:3006/api/addbook', {
bookname: '水浒传',
author: '施耐庵',
publisher: '天津图书出版社'
}, function(res) {
console.log(res); //{status: 201, msg: '添加图书成功'}
})
})
})
</script>
</body>
</html>
4.$.ajax()函数
功能综合的函数,允许我们对Ajax请求进行更详细的配置
$.ajax({
type: '', //请求的方式,Get或者Post
url:'', //请求的url地址
data:{}, //这次请求要携带的数据
success: function(res){} //请求成功后的回调函数
})
发起GET请求
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>发起GET请求</title>
<script src="../lib/jquery.min.js"></script>
</head>
<body>
<button id="btnGET">发起Get请求</button>
<script>
$(function() {
$('#btnGET').on('click', function() {
$.ajax({
type: 'GET', //大小写都行 建议大写
url: 'http://www.liulongbin.top:3006/api/getbooks',
data: { //可以省略
id: 1
},
success: function(res) {
console.log(res); //{status: 200, msg: '获取图书列表成功', data: Array(1)}
}
})
})
})
</script>
</body>
</html>
发起POST请求
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>发起POST请求</title>
<script src="../lib/jquery.min.js"></script>
</head>
<body>
<button id="btnPOST">发起POST请求</button>
<script>
$(function() {
$('#btnPOST').on('click', function() {
$.ajax({
type: 'POST',
url: 'http://www.liulongbin.top:3006/api/addbook',
data: { //传递数据
bookname: '史记',
author: '司马迁',
publisher: '上海图书出版社'
},
success: function(res) {
console.log(res); //{status: 201, msg: '添加图书成功'}
}
})
})
})
</script>
</body>
</html>
七.接口
使用Ajax请求数据时,被请求的URL地址,就叫做数据接口(简称接口)。同时,每个接口必须有请求方式。
1.通过GET方式请求接口的过程
用户希望从服务器中获取数据,于是与网页进行交互,网页发起GET数据请求到服务器,服务器处理请求之后,响应GET请求后把数据返回给前端网页,展示给用户。
2.通过POST方式请求接口的过程
用户与网页交互,并且用户希望在网页上提交数据,借助网页中的Ajax发起POST请求到服务器,服务器内部会进行处理,响应POST请求到网页,最后把结构呈现给用户。
3.接口测试工具
为了验证接口是否能被正常访问,需要接口测试工具,来对数据接口进行验证。
好处:接口测试工具能让我们在不写任何代码的情况下,对接口进行调用和测试。
GET
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KMYMoydM-1676954581193)(C:\Users\t-y-x\AppData\Roaming\Typora\typora-user-images\image-20230205215916105.png)]
POST
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n9SN9ZO5-1676954581194)(C:\Users\t-y-x\AppData\Roaming\Typora\typora-user-images\image-20230205215645639.png)]
4.接口文档
接口的说明文档,他是我们调用接口的依据。一个合格的参考文档,应该包含以下6项基本内容:
1.接口名称
2.接口的url地址
3.接口的调用方式
4.参数的格式
5.响应格式
6.返回示例
案例-图书管理
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y8RMC91Y-1676954581194)(C:\Users\t-y-x\AppData\Roaming\Typora\typora-user-images\image-20230206122051045.png)]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>图书管理</title>
<link rel="stylesheet" href="bootstrap3.4.1/css/bootstrap.css" />
<script src="bootstrap3.4.1/js/jquery.min.js"></script>
</head>
<body style="padding: 15px;">
<!-- 添加图书的pannel面板 -->
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">添加新图书</h3>
</div>
<!-- form-inline让子元素在一行显示 -->
<div class="panel-body form-inline">
<div class="input-group">
<div class="input-group-addon">书名</div>
<input type="text" class="form-control" id="iptBookName" placeholder="请输入书名">
</div>
<div class="input-group">
<div class="input-group-addon">作者</div>
<input type="text" class="form-control" id="iptBookAuthor" placeholder="请输入作者">
</div>
<div class="input-group">
<div class="input-group-addon">出版社</div>
<input type="text" class="form-control" id="iptPublish" placeholder="请输入出版社">
</div>
<button id="btnAdd" class="btn btn-primary">添加</button>
</div>
</div>
<!-- 图书表格 -->
<table class="table table-bordered table-hover">
<thead>
<tr>
<th>Id</th>
<th>书名</th>
<th>作者</th>
<th>出版社</th>
<th>操作</th>
</tr>
</thead>
<tbody id="tb">
</tbody>
</table>
<script>
$(function() {
//从一个网站上 获取一些图书的信息显示到自己写的页面上
//获取图书列表的方法
function getBookList() {
//用get方法取数据 这个是网址 res可以接受返回的信息
$.get('http://www.liulongbin.top:3006/api/getbooks', function(res) {
//进行状态值判断 不是200就是没有找到 提示用户失败
if (res.status != 200) return alert('获取数据失败!')
//定义一个数组 存放res中的数据 用each遍历 jquery中的方法
var rows = [];
$.each(res.data, function(i, item) { //i是循环中的索引位置 item是每个图书对象 i是索引值 通过item.的方式得到内容放到界面上
//push() 把括号里面的东西添加到 数组中
rows.push('<tr><td>' + item.id + '</td><td>' + item.bookname + '</td><td>' + item.author + '</td><td>' + item.publisher + '</td><td><a href="javascript:;" class="del" data-id="' + item.id + '">删除</a></td></tr>')
})
//获得id值为td的标签 先用empty清除子级元素 在append()添加 rows数组里面的 并且用join方法转换为字符串
$('#tb').empty().append(rows)
})
}
getBookList()
//通过代理的方式为 动态添加的元素绑定点击事件
//为什么不能用普通的方式 因为a链接是动态生成
//动态创建的必须用代理模式才能 绑定事件
$('tbody').on('click', '.del', function() {
//attr是jquery中获取自定义属性的方法
var id = $(this).attr('data-id')
console.log(id);
$.get('http://www.liulongbin.top:3006/api/delbook', {
id: id
}, function(res) {
if (res.status != 200) return alert('删除图书失败!')
//没有经过if判断就会直接展示泪飙
getBookList()
})
})
//添加按钮绑定事件
$('#btnAdd').on('click', function() {
//从文本框中获得值 并且去掉两边的空格符号trim
var bookname = $('#iptBookName').val().trim()
var author = $('#iptBookAuthor').val().trim()
var publish = $('#iptPublish').val().trim()
//长度判断 确定文本框中有内容
if (bookname.length <= 0 || author.length <= 0 || publish.length <= 0) {
return alert('请填写完整的图书信息!');
}
$.post('http://www.liulongbin.top:3006/api/addbook', {
bookname: bookname,
author: author,
publisher: publish
}, function(res) {
if (res.status != 201) return alert('添加失败!')
//重新获取图书类表
getBookList()
//把文本框中的值清空
$('#iptBookName').val()
$('#iptBookAuthor').val()
$('#iptPublish').val()
})
})
})
</script>
</body>
</html>
form表单与模板引擎
一.form表单的基本使用
1.概述
表单在网页中主要是负责数据采集。HTML中的form标签,就是用于采集用户输入的细腻些,并同各国form标签的提交操作,把采集到的信息提交到服务器端进行处理。
2.表单的组成部分
表单标签 表单域 表单按钮
<form action="">
<input type="text" name="email_or_mobile" id="" />
<input type="password" name="password" id="" />
<input type="checkbox" name="remember_me" id="" checked />
<button type="submit">提交</button>
</form>
3.form标签的属性
属性 | 值 | 说明 |
---|---|---|
action | URL地址 | 规定当提交表单时,向何处发送表单数据 |
method | get/post | 规定用什么方式把表单数据提交到action URL |
enctype | application/x-www-form-urlencoded | 表示在发送前编码所有字符 |
规定在发送表单数据前如何对其编码 | multipart/form-data | 不对字符进行编码在使用文件上传控件的时候必须使用该值 |
text/plain | 空格转换为+,但不对特殊字符编码 和少用! | |
target | _blank | 在新窗口打开** |
规定在何处打开action URL | _self | 默认 在这个窗口中打开** |
_parent | 在父框架集中打开(less) | |
_top | 在整个窗口中打开(less) | |
framename | 在指定的框架中打开(less) |
action属性
用来指定向哪里发送表单数据,当未指定时,action的默认值为当前页面的URL地址。但指定URL地址时页面会立即跳转到action属性指定的URL地址
target属性
规定在何处打开URL。有五个值!
method属性
用来规定用什么方式提交表单数据get/post(不区分大小写)。默认情况下的值为get,表示通过URL地址的形式,把表单数据提交到action URL。POST情况下会在URL地址中隐藏表单中的数据。get方式适合用来提交少量的、简单的数据。post方式适合用来提交大量的、复杂的、或包含文件上传的数据。
enctype属性
用来规定在发送表单数据之前如何对数据进行编码。默认是application/x-www-form-urlencoded,表示在发送前编码所有字符。在涉及文件上传的操作的时候,必须将enctype的值设置为multipart/form-data。其他情况下用默认的就行。
4.表单的同步提交和缺点
表单的同步提交
通过点击submit按钮,触发表单提交时间,从而使页面跳转到action URL的行为,叫做表单的同步提交
表单同步提交的缺点
form表单同步提交后整个页面都会发生跳转,跳转到action URL所指向的地址,用户体验差。
其次,页面之前的状态和数据都会丢失。
解决:表单只收集数据,用Ajax将数据提交到服务器中
二.通过Ajax提交表单数据
1.监听表单提交事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>监听表单提交事件</title>
<script src="./lib/jquery.min.js"></script>
</head>
<body>
<form action="/login" id="f1">
<input type="text" name="user_name" id="">
<input type="password" name="password" id="">
<button type="submit">提交</button>
</form>
<script>
$(function() {
//方式一 监听事件
// $('#f1').submit(function() {
// alert('监听成功!')
// });
//方式二
$('#f1').on('submit', function() {
alert('监听到事件!')
})
})
</script>
</body>
</html>
2.阻止表单默认提交行为
event.preventDefault()函数,来组织表单提交和页面的跳转
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>阻止表单默认提交行为</title>
<script src="./lib/jquery.min.js"></script>
</head>
<body>
<form action="/login" id="f1">
<input type="text" name="user_name" id="">
<input type="password" name="password" id="">
<button type="submit">提交</button>
</form>
<script>
$(function() {
//方式一 监听事件
$('#f1').submit(function(e) {
alert('监听到了表单的提交事件!');
e.preventDefault(); //阻止默认的提交行为
});
//方式二
// $('#f1').on('submit', function(e) {
// alert('监听到了表单的提交事件!')
// e.preventDefault() //阻止默认的提交行为
// })
})
</script>
</body>
</html>
3.快速获取表单数据
serialize() 函数:为了简化表单中数据的获取操作,jQuery提供了这函数,优势在于可以一次性获取到表单中的所有数据。
使用时,必须为每一个表单元素添加name属性!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>快速获取表单数据</title>
<script src="./lib/jquery.min.js"></script>
</head>
<body>
<form action="/login" id="f1">
<input type="text" name="user_name" id="">
<input type="password" name="password" id="">
<button type="submit">提交</button>
</form>
<script>
$(function() {
//方式一 监听事件
// $('#f1').submit(function(e) {
// e.preventDefault(); //阻止默认的提交行为
// var data = $(this).serialize(); //获得表单的数据信息 表单元素必须要有name属性
// console.log(data);
// });
//方式二
$('#f1').on('submit', function(e) {
e.preventDefault() //阻止默认的提交行为
var data = $('#f1').serialize(); //获得表单的数据信息 表单元素必须要有name属性
console.log(data);
})
})
</script>
</body>
</html>
三.案例-评论列表
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EW2Z95Rb-1676954581195)(C:\Users\t-y-x\AppData\Roaming\Typora\typora-user-images\image-20230206195753560.png)]
cmt.js文件
function getCommentList() {
$.ajax({
type: 'GET',
url: 'http://www.liulongbin.top:3006/api/cmtlist',
data: {},
success: function(res) {
if (res.status != 200) return alert('获取评论列表失败!')
var rows = [];
$.each(res.data, function(i, item) {
var str = '<li class="list-group-item"><span class="badge " style="background-color: skyblue;">评论时间:' + item.time + '</span><span class="badge" style="background-color: #F0AD4E;">评论人:' + item.username + '</span>' + item.content + '</li>';
rows.push(str)
})
$('#cmt-list').empty().append(rows.join(''))
}
})
}
getCommentList()
$(function() {
$('#formAddCmt').on('submit', function(e) {
//阻止表单默认提交行为
e.preventDefault()
var data = $(this).serialize()
$.post('http://www.liulongbin.top:3006/api/addcmt', data, function(res) {
if (res.status != 201) return alert('发表评论失败!')
getCommentList()
//[0]把jquery转换为DOM对象 好调用reset方法清空表单内容
$('#formAddCmt')[0].reset()
})
})
})
index.html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>案例-评论列表</title>
<link rel="stylesheet" href="./bootstrap-3.4.1-dist/css/bootstrap.css" />
<script src="./bootstrap-3.4.1-dist/js/jquery.min.js"></script>
<script src="./js/cmt.js"></script>
</head>
<body style="padding: 15px;">
<!-- 评论面板 -->
<form class="panel panel-primary" id="formAddCmt">
<div class="panel-heading">
<h3 class="panel-title">发表评论</h3>
</div>
<div class="panel-body">
<div>评论人: </div>
<input type="text" class="form-control" name="username" />
<div>评论内容: </div>
<textarea name="content" id="" cols="30" rows="10" class="form-control"></textarea>
<button type="submit" class="btn btn-primary">发表评论</button>
</div>
</form>
<!-- 评论列表 -->
<ul class="list-group" id="cmt-list">
<li class="list-group-item">
<span class="badge " style="background-color: skyblue;">评论时间</span>
<span class="badge" style="background-color: #F0AD4E;">评论人</span>
</li>
</ul>
</body>
</html>
四.模板引擎的基本概念
1.渲染UI结构时遇到的问题
在.push的时候会出现很长的html代码(字符串拼接的方式),拼接时要注意引号之间的关系。并且一旦需求发生变化,修改起来也是非常麻烦。
2.模板引擎概述
根据程序员指定的模板结构和数据,自动生成一个完整的HTMl页面。
工作原理:首先指定数据和模板结构,通过模板引擎会形成一个HTML页面
好处:减少了字符串拼接的操作,代码结构清晰,使代码更加易于阅读和维护
五.art-template模板引擎
1.概述
简约、超快的模板引擎(template-web.js)
2.art-template基本使用
首先导入art-template,在window全局会多一个 template(‘模板的ID’,‘渲染的数据对象’),之后定义数据,定义模板,调用template函数,最后渲染HTML结构。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-g4vpKJvL-1676954581195)(C:\Users\t-y-x\AppData\Roaming\Typora\typora-user-images\image-20230206212611583.png)]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>art-template的使用步骤</title>
<!-- 1.导入模板引擎 -->
<!-- 在window全局会多一个 tempalte('模板的ID','渲染的数据对象') -->
<script src="./lib/template-web.js"></script>
<script src="./lib/jquery.min.js"></script>
</head>
<body>
<!-- 前端显示标签 -->
<div id="container"></div>
<!-- type="text/javascript"把所有script标签下面的代码当作 js代码处理 -->
<script type="text/html" id="tpl-user">
<!-- 3.1模板的html结构中必须定义在script标签中 用type="text/html限定script中的代码是html显示 -->
<!-- 3.2加id属性 -->
<!-- 3.3{{}} 占位符 用来填充数据 -->
<h1>{{name}}</h1>
</script>
<script type="text/javascript">
// 2.定义要渲染的数据
var data = {
title: '<h3>用户信息<h3/>',
name: 'zs',
age: 20,
isVIP: true,
regTime: new Date(),
hobby: ['吃饭', '睡觉', '打豆豆']
}
//4.调用函数
var src = template('tpl-user', data)
//渲染HTML结构
$('#container').html(src);
</script>
</body>
</html>
3.使用传统的方式渲染UI结构
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>使用传统的方式渲染UI结构</title>
<script src="./lib/jquery.min.js"></script>
</head>
<body>
<div id="title"></div>
<div>姓名:<span id="name"></span></div>
<div>年龄:<span id="age"></span></div>
<div>会员:<span id="isVIP"></span></div>
<div>注册时间:<span id="regTime"></span></div>
<div>
爱好:
<ul id="hobby">
</ul>
</div>
<script>
var data = {
title: '<h3>用户信息<h3/>',
name: 'zs',
age: 20,
isVIP: true,
regTime: new Date(),
hobby: ['吃饭', '睡觉', '打豆豆']
}
$(function() {
//需要大量的获取id 不方便!!
$('#name').html(data.name);
$('#title').html(data.title);
$('#age').html(data.age);
$('#isVIP').html(data.isVIP);
$('#regTime').html(data.regTime);
var ros = []
$.each(data.hobby, function(i, item) {
ros.push('<li>' + item + '</li>')
})
$('#hobby').html(ros.join(''));
})
</script>
</body>
</html>
4.art-template标准语法
{{}} 内可以进行变量输出,或者循环数组等操作,被称为标准语法。
标准语法-输出
在{{}} 语法中,可以进行变量输出、对象属性的输出、逻辑或输出、加减乘除等表达式输出
标准语法-原文输出
{{@ value}}如果要输出的value值中,包含了HTML标签结构,则需要使用原文输出语法,才能保证HTML标签被正常渲染。
标准语法-条件输出
格式1:{{if value}} if判断条件为真 输出的内容{{/if}}
格式2:{{if v1}} 按需输出的内容 {{else if v2}} 按需输出的内容 {{/if}}
标准语法-循环输出
如果要实现循环输出,则可以在{{}}内,通过each语法循环数组,当前循环的索引使用 i n d e x 进行访问,当前循环项用 index进行访问,当前循环项用 index进行访问,当前循环项用value
{{each 循环的数组}}
{{$index}} {{$value}}
{{/each}}
标准语法-过滤器
需要处理的值以参数的形式传递给过滤器函数,返回值就是输出的新值。所以过滤器的本质就是个function函数!
{{value | filterName}} 过滤器类似管道操作符,他的上一个输出作为下一个输入
过滤器的基本语法格式:template.defaults.imports.filterName = function(value){ return处理的结果}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>art-template的标准语法</title>
<!-- 1.导入模板引擎 -->
<!-- 在window全局会多一个 tempalte('模板的ID','渲染的数据对象') -->
<script src="./lib/template-web.js"></script>
<script src="./lib/jquery.min.js"></script>
</head>
<body>
<!-- 前端显示标签 -->
<div id="container"></div>
<!-- type="text/javascript"把所有script标签下面的代码当作 js代码处理 -->
<script type="text/html" id="tpl-user">
<!-- 3.1模板的html结构中必须定义在script标签中 用type="text/html限定script中的代码是html显示 -->
<!-- 3.2加id属性 -->
<!-- 3.3{{}} 占位符 用来填充数据 -->
<h1>{{name}}</h1>
<!-- {{@原文输出}} -->
{{@ age}}
<!-- {{条件输出}} -->
{{if isVIP !== true}}
<h2>我不是VIP</h2>
{{else if isVIP === true}}
<h2>我是VIP</h2>
{{/if}}
<!-- {{循环输出}} -->
<ul>
{{each hobby}}
<li>索引是:{{$index}},循环项是:{{$value}}</li>
{{/each}}
</ul>
<!-- 过滤器 -->
<h3>注册时间:{{regTime | dateFormat}}</h3>
</script>
<script type="text/javascript">
//定义处理时间的过滤器
template.defaults.imports.dateFormat = function(date) {
var y = date.getFullYear();
var m = date.getMonth() + 1;
var d = date.getDate();
return y + '-' + m + '-' + d;
}
// 2.定义要渲染的数据
var data = {
name: 'maimai',
age: '<h3>18</h3>',
isVIP: true,
hobby: ['吃饭', '睡觉', '写代码'],
regTime: new Date()
};
//4.调用函数
var src = template('tpl-user', data);
//渲染HTML结构
$('#container').html(src);
</script>
</body>
</html>
5.案例-新闻列表
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xcyxauvd-1676954581195)(C:\Users\t-y-x\AppData\Roaming\Typora\typora-user-images\image-20230207132355454.png)]
new.js
$(function() {
//补零函数
function padZero(n) {
if (n < 10) return '0' + n
else return n
}
//定义格式化时间的过滤器
template.defaults.imports.dateFormat = function(dtStr) {
var dt = new Date(dtStr)
var y = dt.getFullYear();
var m = padZero(dt.getMonth() + 1);
var d = padZero(dt.getDate());
var hh = padZero(dt.getHours());
var mm = padZero(dt.getMinutes());
var ss = padZero(dt.getSeconds());
return y + '-' + m + '-' + d + ' ' + hh + ':' + mm + ':' + ss
}
//获取新闻列表的函数
function getNewsList() {
$.get('http://www.liulongbin.top:3006/api/news', function(res) {
if (res.status != 200) return alert('获取新闻列表数据失败!')
for (var i = 0; i < res.data.length; i++) {
//把tags属性值 ,从字符串转换为字符串数组 用逗号分开
res.data[i].tags = res.data[i].tags.split(',')
}
console.log(res);
var htmlStr = template('tpl-news', res)
$('#news-list').html(htmlStr)
})
}
getNewsList()
})
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<link rel="stylesheet" href="./assets/news.css" />
<script src="./lib/jquery.min.js"></script>
<script src="./lib/template-web.js"></script>
<script src="js/news.js"></script>
</head>
<body>
<div id="news-list">
</div>
<!-- 定义模板 -->
<script type="text/HTML" id="tpl-news">
{{each data}}
<div class="news-item">
<img class="thumb" src="{{'http://www.liulongbin.top:3006'+$value.img}}" alt="" />
<div class="right-box">
<h1 class="title">{{$value.title}}</h1>
<div class="tags">
{{each $value.tags}}
<span>{{$value}}</span> {{/each}}
</div>
<div class="footer">
<div>
<span>{{$value.source}}</span>
<span>{{$value.time | dateFormat}}</span>
</div>
<span>评论数:{{$value.cmtcount}}</span>
</div>
</div>
</div>
{{/each}}
</script>
</body>
</html>
六.模板引擎的思想原理
1.正则与字符串操作
1.exec() 函数用来检索字符串中的正则表达式的匹配,如果字符串中有匹配的值,则返回该匹配值,否则返回null
格式:RegExpObject.exec(String)
2.分组:在正则表达式中,用()包起来的表示一个分组 可以通过分组来提取自己想要的内容
3.字符串的replace函数:用于在字符串中用一些字符替换另一些字符
4.字符串的多次replace
5.使用while循环replace:简化多次replace
6.replace替换真值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>模板引擎的思想原理</title>
</head>
<body>
<script>
var str = 'hello'
var pattern = /o/
//exec() 函数
var res = pattern.exec(str)
console.log(res); // 成功返回下面的样式, 失败返回false
/*
Array(1)
0:"o"
groups:undefined
index:4
input:"hello"
length:1 */
</script>
<script>
var str = '<div>我是{{name}}</div>'
//用()包起来的表示一个分组 可以通过分组来提取自己想要的内容
var pattern = /{{([a-zA-Z]+)}}/
var res = pattern.exec(str)
console.log(res); //['{{name}}', 'name', index: 7, input: '<div>我是{{name}}</div>', groups: undefined]
</script>
<script>
//字符串的replace函数
var str = '<div>我是{{name}}</div>';
//([a-zA-Z]+) 提取分组
var pattern = /{{([a-zA-Z]+)}}/
var res = pattern.exec(str)
console.log(res); // ['{{name}}', 'name'] 索引为0 和1处的值
//替换0 和 1处的值
var newStr = str.replace(res[0], res[1])
console.log(newStr); //<div>我是name</div>
console.log(str); //<div>我是{{name}}</div>
</script>
<script>
//字符串的多次replace
var str = '<div>我是{{name}},今年{{age}}</div>';
varpattern = /{{\s*([a-zA-Z]+)\s*}}/;
//第一次匹配
var res1 = pattern.exec(str);
console.log(res1);
//['{{name}}', 'name', index: 7, input: '<div>我是{{name}},今年{{age}}</div>', groups: undefined]
str = str.replace(res1[0], res[1]);
console.log(str);
//<div>我是name,今年{{age}}</div>
//第二次匹配
var res2 = pattern.exec(str);
console.log(res2);
//['{{age}}', 'age', index: 14, input: '<div>我是name,今年{{age}}</div>', groups: undefined]
str = str.replace(res2[0], res[1]);
console.log(str);
//<div>我是name,今年name</div>
</script>
<script>
//使用while循环replace
var str = '<div>我是{{name}},今年{{age}}</div>';
var pattern = /{{\s*([a-zA-Z]+)\s*}}/;
var res = null;
while (res = pattern.exec(str)) {
str = str.replace(res[0], res[1])
}
console.log(str); //<div>我是name,今年age</div>
</script>
<script>
//replace替换真值
var data = {
name: '张三',
age: 15
}
var str = '<div>我是{{name}},今年{{age}}</div>';
var pattern = /{{\s*([a-zA-Z]+)\s*}}/;
var res = null;
while (res = pattern.exec(str)) {
str = str.replace(res[0], data[res[1]])
}
console.log(str);
</script>
</body>
</html>
2.实现简单的模板引擎
实现步骤:1.定义模板结构 2.预调用模板引擎 3.封装template函数 4.导入并使用自定义的模板引擎
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>实现简单的模板引擎</title>
</head>
<body>
<div id="user-box"></div>
<script type="text/html" id="tpl-user">
<div>姓名:{{name}}</div>
<div>年龄:{{age}}</div>
<div>性别:{{gender}}</div>
<div>住址:{{address}}</div>
</script>
<script>
//定义数据
var data = {
name: 'as',
age: 12,
gender: '男',
address: '墨西哥'
}
//调用模板引擎
var htmlStr = template('tpl-user', data)
//渲染到页面上
document.querySelector('#user-box').innerHTML = htmlStr;
//自己定义的模板引擎
function template(id, data) {
var str = document.getElementById(id).innerHTML;
var pattern = /{{\s*([a-zA-Z]+)\s*}}/
var patternRes = null;
while (patternRes = pattern.exec(str)) {
str = str.replace(patternRes[0], data[patternRes[1]])
}
return str;
}
</script>
</body>
</html>
Ajax加强!
一.XMLHttpRequest的基本使用
1.概述
XMLHttpRequest(简称xhr)是浏览器提供的JavaScript对象,通过这个可以访问浏览器资源。jQuery中的Ajax函数,就是基于xhr对象封装出来的。
2.使用xhr发起GET请求
步骤:创建xhr对象 调用xhr.open()函数 调用xhr.send()函数 监听xhr.onreadystatechange事件
本质:当需要携带参数的时候本质上,都是直接将参数以查询字符串的形式,追加到URl地址的后面,发送到服务器的
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>使用xhr发起GET请求</title>
</head>
<body>
<script>
//1.创建一个xhr对象
var xhr = new XMLHttpRequest();
//2.调用open函数
//xhr.open('GET', 'http://www.liulongbin.top:3006/api/getbooks');
//使用xhr发起带参数的GET请求
xhr.open('GET', 'http://www.liulongbin.top:3006/api/getbooks?id=3');
//3.调用send函数
xhr.send()
//4.监听 onreadystatechange 事件
xhr.onreadystatechange = function() {
//xhr.readyState === 4 && xhr.status ===200 固定写法判断有没有响应成功
if (xhr.readyState === 4 && xhr.status === 200) {
//获取响应的数据
console.log(xhr.responseText);
}
}
</script>
</body>
</html>
3.了解xhr对象的readyState属性
XMLHttpRequest对象的readyState属性,表示当前Ajax请求所处的状态,每个Ajax请求必然处于以下状态之一:
值 | 状态 | 描述 |
---|---|---|
0 | UNSENT | XMLHttpRequest对象被已被创建,但尚未调用open()方法 |
1 | OPENED | open()方法已经被调用 |
2 | HEADERS_RECEIVEND | send()方法已经被调用,响应头也已经被接收 |
3 | LOADING | 数据接收中,此时response属性已经包含部分数据 |
4 | DONE | Ajax请求完成,意味着数据传输已经彻底完成或者失败 |
4.查询字符串
定义:是指在URL的末尾加上用于向服务器发送信息的字符串(变量)
格式:将英文的?放在URL的末尾,然后再加上参数=值,多个参数的时候使用&符号分开。以这种形式把此案要发送给服务器的数据添加到URL中
5.URL编码与解码
URL地址中只允许出现英文相关的字母、标点符号、数字。因此如果出现中文字符得进行编码(转义)
URL编码的原则:使用安全的字符(没有特殊用途或者特殊意义的可打印的字符)去表示那些不安全的字符。使用英文字符去表示非英文字符。
对URL进行编码和解码:
encodeURI():编码函数
decodeURI():解码函数
注意:由于浏览器会自动对URL地址进行编码操作,因此大多数情况下,不需要关心URL地址的编码和解码操作!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>URL编码与解码</title>
</head>
<body>
<script>
var str = '我叫陈伟霆';
var res = encodeURI(str);
console.log(res); //%E6%88%91%E5%8F%AB%E9%99%88%E4%BC%9F%E9%9C%86
var str2 = '%E9%99%88%E4%BC%9F%E9%9C%86';
var res2 = decodeURI(str2);
console.log(res2); //陈伟霆
</script>
</body>
</html>
6.使用xhr发起POST请求
步骤:创建xhr对象 调用xhr.open()函数 设置Content-Type属性 调用xhr.send()函数,在括号中可以指定发送的数据 监听xhr.onreadystatechange事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>使用xhr发起POST请求</title>
</head>
<body>
<script>
//1.创建xhr对象
var xhr = new XMLHttpRequest()
//2.调用open函数
xhr.open('POST', 'http://www.liulongbin.top:3006/api/addbook')
//3.设置Content-type属性 固定写法!! 放在open之后 send之前!
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
//4.调用send函数
xhr.send('bookname=水浒传&author=施耐庵&publisher=上海图书出版社')
//5.监听事件
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(xhr.responseText);
}
}
</script>
</body>
</html>
二.数据交换格式
1.概述
数据交换格式,指服务器端与客户端之间进行数据传输与交换的格式 ,有XML和JSON。前者很少,重点学JSON!
2.XML
概述
XML就是可扩展的标记语言。与HTML类似也是一种标记语言
与HTML的区别
虽然都是标记语言,但是他俩没有任何关系,HTML被设计描述网页上的内容,而XML被设计用来传输和储存数据,是数据的载体
缺点
格式臃肿,和数据无关的代码过多,体积大,传输效率低。在JavaScript中解析XML比较麻烦
3.JSON
概述
JavaScript对象表示法。简单来说,JSON就是JavaScript对象和数组字符串表示法,他使用文本表示一个JS对象或数组信息,因此JSON的本质是字符串,用字符串表示Javascript对象数据或数组数据
作用与现状
JSON是一种轻量级的文本数据交换格式,在作用上类似XML,专门用于储存和传输数据,JSON比XML更小,更快,更易解析。
JSON作用在计算机与网络之间存储和传输数据!
JSON已经成为主流的数据交换格式!
JSON两种结构
对象结构
{key:value,key:value,key:value, …}
其中key必须是使用英文的双引号包裹的字符串,value的值可以是数字、字符串、布尔值、null、数组、对象6种类型
ps:当值为字符串时必须用英文下双引号包裹,不能用undefined。value值不能是function!
数组结构
[“java”,“javascript”,20,true …] 数组对象中的数据类型可以是数字、字符串、布尔值、null、数组、对象6种类型
JSON注意事项
属性名和字符串类型的值必须用双引号包裹,JSON种不允许使用单引号表示字符串,JSON不能使用注释,JSON最外层必须是对象{}或者数组[]格式,不能使用undefined或函数作为JSON值
JSON和JS对象的关系
JSON是JS对象的字符串表示法,他使用文本表示一个JS对象的信息,本质就是一个字符串!
//这是一个对象
var obj = {a:'hello', b:'world'}
//这是一个JSON字符串
var json = '{"a":"Hello", "b":"World"}'
JSON和JS对象的互换
JSON.parse()方法:JSON转换为JS对象
JSON.stringify()方法:JS对象转换为JSON对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JSON和JS对象的转换</title>
</head>
<body>
<script>
//这是一个JS对象
var js = {
a: 'hello',
b: 'world'
}
//这是一个JSON字符串
var jsonStr = '{"a":"Hello", "b":"World"}';
//JSON转换为JS对象!
var obj = JSON.parse(jsonStr);
console.log(obj); //{a: 'Hello', b: 'World'}
//JS对象转换为JSON对象
var str = JSON.stringify(js);
console.log(str); //{"a":"hello","b":"world"}
</script>
</body>
</html>
parse方法的应用场景
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>演示</title>
</head>
<body>
<script>
var xhr = new XMLHttpRequest()
xhr.open('GET', 'http://www.liulongbin.top:3006/api/getbooks')
xhr.send()
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(xhr.responseText); //xhr.responseText是一个JSON格式的字符串
console.log(typeof xhr.responseText); //string
//把获得的JSON数据转换为JS对象方便操作!!
var res = JSON.parse(xhr.responseText);
console.log(res);
}
}
</script>
</body>
</html>
序列化和反序列化
把数据对象转换为字符串的过程叫做序列化,例如 JSON.stringify() 函数的操作(序列化函数) ,叫做JSON的序列化。
把字符串转换为数据对象的过程叫反序列化,例如 JSON.parse() 函数的操作(反序列化函数) ,叫做JSON的反序列化。
三.封装自己的Ajax函数
mi.js
function resolveData(data) {
var arr = []
for (var k in data) {
var str = k + '=' + data[k]
arr.push(str)
}
return arr.join('&')
}
//测试!
// var res = resolveData({ name: 'zs', age: 20 }) //name=zs&age=20
// console.log(res);
function mi(options) {
var xhr = new XMLHttpRequest()
//把外界传递过来的参数对象 转换为查询字符串
var qs = resolveData(options.data)
//判断不同的请求类型
if (options.method.toUpperCase() === 'GET') {
//发起get请求
xhr.open(options.method, options.url + '?' + qs)
xhr.send()
} else if (options.method.toUpperCase() === 'POST') {
//发起POST请求
xhr.open(options.method, options.url)
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
xhr.send(qs)
}
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
var res = JSON.parse(xhr.responseText)
options.success(res)
}
}
}
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="js/mi.js"></script>
</head>
<body>
<script>
//测试get请求
/* mi({
method: 'GET',
url: 'http://www.liulongbin.top:3006/api/getbooks',
data: {
id: 2
},
success: function(res) {
console.log(res);
}
}); */
//测试post请求
mi({
method: 'POST',
url: 'http://www.liulongbin.top:3006/api/addbook',
data: {
bookname: '水货转',
author: 'sna',
publisher: '九九九'
},
success: function(res) {
console.log(res);
}
})
</script>
</body>
</html>
四.XMLHttpRequest Level2的新特性
1.概述
1.旧版的XMLHttpRequest缺点:
只支持文本数据的传输,无法用来读取和上传文件。传输和接收数据时,没有进度信息,只能提示有没有完成
2.XMLHttpRequest Level2的新功能:
可以设置HTTP请求的时限,可以使用FormData对象管理表单数据,可以上传文件,可以获得数据传输的进度信息
2.设置HTTP请求时限
得到XMLHttpRequest对象,增加了timeout属性,可以设置HTTP请求的时限
格式:
//设置最长等待时间为3000毫秒,超过时间就会自动停止HTTP请求。
xhr.timeout = 3000
//ontimeout事件,用来指定回调函数!
xhr.ontimeout = function(event){
alert('请求超时!')
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>设置HTTP请求的时限</title>
</head>
<body>
<script>
var xhr = new XMLHttpRequest();
//设置超时时间
xhr.timeout = 3;
//设置超时以后的处理函数
xhr.ontimeout = function() {
alert('超时了')
}
xhr.open('GET', 'http://www.liulongbin.top:3006/api/getbooks')
xhr.send()
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(xhr.responseText);
}
}
</script>
</body>
</html>
3.使用FormData对象管理表单数据
Ajax操作往往用来提交表单数据,为方便表单处理,HTML5新增了一个FormData对象,可以模拟表单操作!
FormData对象的基本使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>FormData对象的基本使用</title>
</head>
<body>
<script>
//1.创建FormData对象
var fd = new FormData();
//2.调用append函数, 向fd种追加数据
fd.append('uname', 'za');
fd.append('upwd', '12345');
//创建一个xhr对象
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://www.liulongbin.top:3006/api/formdata')
xhr.send(fd)
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(xhr.responseText);
//{"message":"测试FormData表单提交成功!","data":{"uname":"za","upwd":"12345"}}
}
}
</script>
</body>
</html>
FormData对象快速获取表单中的数据
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>FormData对象快速获取表单中的数据</title>
</head>
<body>
<form id="form1" action="">
<input type="text" name="uname" autocomplete="off" id="">
<input type="password" name="upwd" id="">
<button type="submit">提交</button>
</form>
<script>
//1.通过DOM操作,获取到form表单元素
var form = document.querySelector('#form1')
form.addEventListener('submit', function(e) {
//阻止表单默认提交行为
e.preventDefault()
//创建formdata 快速获取到form表单中的数据
var fd = new FormData(form)
var xhr = new XMLHttpRequest()
xhr.open('POST', 'http://www.liulongbin.top:3006/api/formdata')
xhr.send(fd)
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(JSON.parse(xhr.responseText));
}
}
})
</script>
</body>
</html>
4.XMLHttpRequest Level2上传文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>XMLHttpRequest Level2上传文件</title>
<link rel="stylesheet" href="./bootstrap3.4.1/css/bootstrap.css">
<script src="./bootstrap3.4.1/js/jquery.min.js"></script>
</head>
<body>
<!-- 1.文件选择框 -->
<input type="file" id="file1">
<!-- 2.上传文件的按钮 -->
<button id="btnUpload">提交</button>
<!-- 进度条 -->
<div class="progress" style="width: 500px;margin:15px 10px">
<div class="progress-bar progress-bar-striped active" style="width: 0%" id="percent">
0%
</div>
</div>
<!-- 3.image标签 显示上传成功后的图片 -->
<img src="" alt="" id="img" width="800">
<script>
//获取到文件上传按钮
var btnUpload = document.querySelector('#btnUpload')
//为按钮绑定事件处理函数
btnUpload.addEventListener('click', function() {
//判断用户是否选择文件
var files = document.querySelector('#file1').files
if (files.length <= 0) {
return alert('请选择要上传的文件!')
}
//向formdata中添加图片 用append方法
var fd = new FormData()
fd.append('lishiyu', files[0])
//上传文件
var xhr = new XMLHttpRequest()
//监听文件上传进度 xhr.upload.onprogress 获取文件上传进度
xhr.upload.onprogress = function(e) {
//e.lengthComputable是一个boolean值 表示当前上传资源是否具有可计算的长度
if (e.lengthComputable) {
//计算出上传的进度
//e.loaded 已传输的字节
//e.total 需要传输的总字节
var procentComplete = Math.ceil((e.loaded / e.total) * 100);
//获取进度条并且动态设置
$('#percent').attr('style', 'width:' + procentComplete + '%').html(procentComplete + '%');
}
}
//监听上传完成事件
xhr.upload.onload = function() {
//removeClass() 移除上传中的类样式
//addClass() 添加上传完成的样式
$('#percent').removeClass().addClass('progress-bar progress-bar-success')
}
xhr.open('POST', 'http://www.liulongbin.top:3006/api/upload/avatar');
//把文件发送到服务器
xhr.send(fd);
//监听事件 拿到服务器中的图片
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
var data = JSON.parse(xhr.responseText);
console.log(data);
//{message: '上传文件成功!', status: 200, url: '/uploads/1675838387072_a15b188c238e477ca4d4647ae286ac04.jpg'}
if (data.status === 200) { //上传成功
var img = document.querySelector('#img')
img.src = 'http://www.liulongbin.top:3006' + data.url
} else { //上传失败
console.log('图片上传失败!');
}
}
}
})
</script>
</body>
</html>
五.jQuery高级用法
jQuery实现文件上传
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nf6NNd8H-1676954581196)(C:\Users\t-y-x\AppData\Roaming\Typora\typora-user-images\image-20230208160924962.png)]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>jQuery实现文件上传</title>
<script src="bootstrap3.4.1/js/jquery.min.js"></script>
</head>
<body>
<input type="file" id="file1">
<button id="btn">上传文件</button>
<br>
<img src="img/loading.gif" alt="" style="display: none; width: 100px;" id="loading">
<script>
$(function() {
//监听到Ajax请求被发起 ajaxStart
$(document).ajaxStart(function() {
$('#loading').show()
})
//监听到Ajax请求完成 ajaxStop
$(document).ajaxStop(function() {
$('#loading').hide()
})
$('#btn').on('click', function() {
var files = $('#file1')[0].files
if (files.length <= 0) {
return alert('请选择文件后上传');
}
var fd = new FormData()
fd.append('avater', files[0])
//发起jQuery的Ajax请求 上传文件
$.ajax({
//上传文件只能用POST请求
method: 'POST',
url: 'http://www.liulongbin.top:3006/api/upload/avatar',
data: fd,
//上传文件必须指定这两个值为false
processData: false,
contentType: false,
success: function(res) {
console.log(res);
}
})
})
})
</script>
</body>
</html>
六.axios
1.概述
Axios是专注于网络数据请求的库
相比于原生的XMLHttpRequest对象,axios简单易用,相比于jQuery,axios更加轻量化,只专注于网络数据请求。
2.axios发送请求的三种方式
//1.GET请求语法:
axios.get('url', {params:{参数}}).then(callback)
//2.POSRT请求语法:
axios.post('url', {参数}).then(callback)
//3.直接使用axios发送get/post请求语法:
axios({
method:'请求类型',
url:'请求的URL地址',
data:{//post参数},
params: {//GET参数}
}).then(callback)
实例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>用Axios发起GET请求</title>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
</head>
<body>
<button id="btnGet">发起get请求</button>
<button id="btnPost">发起post请求</button>
<button id="btnAxiosGet">直接使用Axios发送get请求</button>
<button id="btnAxiosPost">直接使用Axios发送post请求</button>
<script>
//发起get请求
var btnGet = document.querySelector('#btnGet');
btnGet.addEventListener('click', function() {
var url = 'http://www.liulongbin.top:3006/api/get'
var paramsObj = {
name: 'zs',
age: 20
}
axios.get(url, {
params: paramsObj
}).then(function(res) {
//有六个属性 其中data才是浏览器返回的属性,其他的都是axios包装的
console.log(res);
console.log(res.data);
//{message: 'GET请求测试成功', query: {…}}
})
});
//发送post请求
document.querySelector('#btnPost').addEventListener('click', function() {
var url = 'http://www.liulongbin.top:3006/api/post'
var dataObject = {
adress: '北京',
location: '珠海区'
}
axios.post(url, dataObject).then(function(res) {
console.log(res.data);
})
});
//直接使用Axios发送get请求
document.querySelector('#btnAxiosGet').addEventListener('click', function() {
axios({
method: 'GET',
url: 'http://www.liulongbin.top:3006/api/get',
params: {
name: 'zs',
age: 20
},
}).then(function(res) {
console.log(res.data);
})
});
//直接使用Axios发送post请求
document.querySelector('#btnAxiosPost').addEventListener('click', function() {
axios({
method: 'POST',
url: 'http://www.liulongbin.top:3006/api/post',
data: {
adress: '北京',
location: '珠海区'
},
}).then(function(res) {
console.log(res.data);
})
});
</script>
</body>
</html>
=“btnAxiosGet”>直接使用Axios发送get请求
直接使用Axios发送post请求