Ajax的应用场景:
1、页面上拉加载更多数据
2、列表数据无刷新分页
3、表单项离开焦点数据验证
4、搜素框提示文字下拉列表
Ajax运行原理:
服务器端响应的数据格式:在http请求与响应的过程中,无论是请求参数还是响应内容,如果是对象类型,最终都会被转换为对象字符串进行传输(这是规定)
浏览器端还需要把服务器端响应的json字符串转换为json对象
/* 在http请求与响应的过程中,无论是请求参数还是响应内容,如果是对象类型,最终都会被转换为对象字符串进行传输(这是规定)
客户端还需要把服务器端响应的json字符串转换为json对象 */
var responseText = JSON.parse(xhr.responseText)
请求报文:在Http请求和响应的过程中传递的数据块就叫报文,包括要传送的数据和一些附加信息,这些数据和信息要遵守规则和定好的格式
请求参数的格式
1、application/x-www-form-urlencoded
name=zhangsan&age=20&sex=男
2、application/json
{name:'zhangsan',age:'20',sex:'男'}
在请求头中指定Content-Type属性的值是application/json,告诉服务器当前请求参数的格式是json
JSON.stringify() //将json对象转换为json字符串
注意:get请求是不能提交json对象数据格式的,传统网站的表单也是不支持json对象数据格式的
请求类型:分为get请求和post请求
Get请求:参数在URL后面,多个参数用&进行连接
Post请求:参数在请求体中
Ajax状态码:
xhr.readyState // 获取Ajax状态码
0:请求未初始化(还没有调用open())
1:请求已经建立,但是还没有发送(还没有调用send())
2:请求已经发送
3:请求正在处理中,通常响应中已经有部分数据可以用了
4:响应已经完成,可以获取并使用服务器的响应了
http常见的状态码:
xhr.status // 获取http常见的状态码
200:表示响应成功
404:没有找到请求的资源
500:服务器端错误
同源政策
同源:协议,域名,端口这三者条件必须相同
为什么会有同源政策?
——为了保证用户信息的安全,防止恶意的网站窃取数据。
同源政策是浏览器给予Ajax技术的限制,服务器端是不存在同源政策限制。
Ajax请求限制:Ajax只能向自己的服务器发送请求。
解决跨域问题
Ajax是为了访问自己服务器的数据,跨域是为了访问别人服务器的数据
1、CORS 跨域资源共享/非同源资源共享,它允许浏览器向跨域服务器发送Ajax请求,克服了Ajax只能同源使用的限制
2、使用JSONP解决同源限制问题,它不属于Ajax请求,但是它可以模拟Ajax请求
jsonp的原理与实现
(1)首先是利用script标签的src属性来实现跨域。
<body>
<script>
// 2、定义函数
function fun(data) {
console.log('客户端的fun函数被调用')
console.log(data)
}
</script>
<!-- 1、将非同源服务器端的请求地址写在script标签的src里面 -->
<!-- 把函数名传递给服务器 -->
<script src="http://localhost:3001/test?callback=fun"></script>
</body>
(2)通过将前端方法作为参数传递到服务器端,然后由服务器端注入参数之后再返回,实现服务器端向客户端通信。
app.get('/test', (req, res) => {
const name = req.query.callback
const result = name + '({name:"zhangsan"})'
res.send(result)
})
(3)由于使用script标签的src属性,因此只支持get方法
3、服务器进行跨域,浏览器吧请求发送给自己的服务器,之后自己的服务器去访问其他的服务器数据,再返回给浏览器,绕过了浏览器的同源策略
// 客户端访问自己服务器 s1
<script src="./js/ajax.js"></script>
<script>
// 获取按钮元素
var btn = document.getElementById('btn')
btn.onclick = function() {
ajax({
url: 'http://localhost:3000/server',
type: 'get',
success: function(result) {
console.log(result)
}
})
}
</script
// s1 服务器访问s2服务器
// 对应s1中 06html文件
app.get('/server', (req, res) => {
// 访问s2的服务器,需要借助第三方模块 request
request('http://localhost:3001/cors', (err, response, body) => {
res.send(body)
})
})
JSONP与CORS区别
实际上,cors和jsonp都是用于解决跨域问题,当两个页面的协议、域名、端口号中有一个不一致时就存在了跨域,一旦出现跨域,浏览器发送跨域请求后,请求回来的数据都会被浏览器所拦截。
JSONP的原理是动态创建script标签
1.JSONP发送的不是ajax请求
2.JSONP不支持post请求
3.JSONP没有兼容问题
CORS中文意思是跨域资源共享,需要在服务器端设置cops配置
1.CORS发送的是真正的ajax请求
2.CORS既支持get 又支持post
3.有兼容问题,只有ie10及以上才支持
withCredentials
withCredentials:指定在涉及到跨域请求时,是否携带cookie信息,默认值为false。
在使用Ajax技术发送跨域请求时,默认情况下不会在请求中携带cookie信息。
// 在服务器中添加这样一句话
// 允许客户端发送跨域请求时携带cookie信息
res.header('Access-Control-Allow-Credentials', true)
//下拉框改变事件
province.onchange = function() {}
//用户输入事件
user.oninput=function(){}
防抖与节流知识点
防抖:指在事件触发n秒后再执行回调,如果在n秒内再次被触发,则重新计算时间。比如说,我点击屏幕,八秒后出现结果,但是我在八秒内又点击屏幕,之后又要等八秒才有结果,我一直点就会一直重新等八秒,直到我最后一次点,等八秒就有结果。
主要应用场景有:
a、scroll事件滚动触发,
b、搜索框输入查询
c、表单验证
d、按钮提交事件
e、浏览器窗口缩放,resize事件
节流:如果持续触发某个事件,则每隔n秒执行一次。比如,我点击屏幕,八秒显示结果,我点第一次,点第二次,点第三次……,等八秒出现点击第一次的结果,之后又出现第二次的结果,……有点点像卡顿的那种,你每次的点击,都会等八秒才给你响应。
主要应用场景:
a、DOM元素的拖拽功能实现
b、射击游戏类
c、计算鼠标移动的距离
d、监听scroll事件
key.trim() //内容去空格
FormData对象的作用
1.模拟HTML表单,相当于将HTML表单映射成表单对象,自动将表单对象中的数据拼接成请求参数的格式。
// 客户端
<script>
// 获取提交按钮
var btn = document.getElementById('btn')
// 获取表单
var form = document.getElementById('form')
btn.onclick = function() {
// 将普通表单转化为FormData表单
// formData只能使用post请求发送
var formData = new FormData(form)
// 使用ajax发送数据
// 1、创建ajax
var xhr = new XMLHttpRequest();
// 2、发送请求发送和地址
xhr.open('post', "http://localhost:3000/formData")
// 3、发送
xhr.send(formData)
// 4、监听xhr对象事件
xhr.onload = function() {
if (xhr.status == 200) {
console.log(xhr.responseText);
}
}
}
</script>
// 服务端
app.post('/formData', (req, res) => {
// 创建一个formdata表单解析对象
const from = new formidable.IncomingForm();
// 解析客户端传过来的formData对象
from.parse(req, (err, fields, files) => {
res.send(fields)
})
})
2.异步上传二进制文件
// 客户端
<body>
<div class="container">
<div class="from-group">
<label> 请选择文件</label>
<input type="file" id="file">
<!-- 显示图片 -->
<div class="padding" id="imgBox"></div>
<!-- 进度条 -->
<div class="progress">
<div class="progress-bar" style="width:0%" id="bar">0%</div>
</div>
</div>
</div>
<script>
// 获取文件内容
var file = document.getElementById('file');
// 为文件选择控制添加 onchange 事件
// 在用户选择文件时触发
file.onchange = function() {
// 创建一个formData表单对象
var formData = new FormData();
// 获取进度条元素
var bar = document.getElementById('bar')
// 获取图片容器
var imgBox = document.getElementById('imgBox')
// 把获取的文件追加到formData对象中区
// 第二个参数是文件files,但我们就选择一个文件,所以是this.files[0],不管选了多少个文件,files都是一个集合,要注意写法
formData.append('attrName', this.files[0])
// 创建ajax对象
var xhr = new XMLHttpRequest()
// 对ajax对象进行配置
xhr.open('post', 'http://localhost:3000/upload')
// 文件上传过程中持续触发
xhr.upload.onprogress = function(ev) {
// ev.loaded 文件已经上传了多少
// ev.total 上传文件的总大小
var results = (ev.loaded / ev.total) * 100 + '%';
// 把进度结果发到进度条内容中
bar.style.width = results;
bar.innerHTML = results;
}
// 发送ajax对象
xhr.send(formData);
// 监听服务器端响应给客户端的数据
xhr.onload = function() {
if (xhr.status == 200) {
// 将服务器端返回的JSON字符串转换为JSON对象
var result = JSON.parse(xhr.responseText)
// 动态创建img标签
var img = document.createElement('img')
// 给图片标签设置src属性
img.src = result.path;
// 当图片加载完成以后
img.onload = function() {
// 将图片显示在页面中
imgBox.appendChild(img)
}
}
}
}
</script>
</body>
// 服务端
app.post('/upload', (req, res) => {
// 创建一个formdata表单解析对象,设置保留文件后缀名
const form = new formidable.IncomingForm({ keepExtensions: true });
// 设置客户端上传文件的存储路径
form.uploadDir = path.join(__dirname, 'public', 'uploads');
// 解析客户端传过来的formData对象
form.parse(req, (err, fields, files) => {
// 服务器要把图片地址返回给客户端
res.send({
path: files.attrName.filepath.split('public')[1]
})
})
})
FormData对象只能使用post请求方式
FormData对象的属性
// 获取表单对象的值
formData.get('key');//key是name属性的值
// 设置表单对象中属性的值
// 如果设置的表单属性不存在,则会创建这个表单属性,如果存在则会覆盖
formData.set('key','value');
// 删除表单对象中属性的值
formData.delete('key');
// 向表单对象中追加属性值
formData.append('key','value')
// 例如:创建空的表单对象
var f = new FormData();
f.append('sex','男');
console.log(f.get('sex'));
注意: set方法与append 方法的区别是,在属性名已存在的情况下,set会覆盖已有键名的值,append会保留两个值。
Jquery中 $.ajax()
作用:发送Ajax请求
<script src="./js/jquery.min.js"></script>
<script>
// 使用jquery
$('#btn').on('click', function() {
// 使用jQuery中的ajax
$.ajax({
//请求方式
type: 'post',
// 请求地址
// 如果访问自己的服务器,可以省去协议,域名,端口
url: '/user',
data: {
name: 'lisi',
age: '18',
},
// 在请求发送之前调用
beforeSend: function() {
alert('请求不会被发送')
// 请求不会被发送
return false
},
// 指定参数的格式类型
contentType: 'application/json',
// 请求成功以后函数被调用
success: function(response) {
// response为服务器端返回的数据
// 方法内部会自动将json字符串转换为json对象
console.log(response)
},
// 请求失败以后函数被调用
error: function(xhr) {
console.log(xhr)
}
})
})
</script>
serialize方法
作用:将表单中的数据自动拼接成字符串的参数
<script type="text/javascript">
// 提交事件
$('#form').on('submit', function() {
// 将表单内容拼接成字符串类型的参数
var param = $('#form').serialize()
console.log(param)
return false
})
</script>
$.ajax方法发送jsonp请求
// 客户端
<script src="./js/jquery.min.js"></script>
<script>
$('#btn').on('click', function() {
$.ajax({
url: '/jsonp',
// 指定当前发送jsonp请求
dataType: 'jsonp',
// 修改callback参数名称
// jsonp: 'cb',
// 指定函数名称 ,如果你不想要success这个函数,你可以通过这个自己创一个函数,要提前先定义好函数
// jsonpCallback: 'fnName',
success: function(response) {
console.log(response)
}
})
})
</script>
// 服务端
app.get('/jsonp', (req, res) => {
res.jsonp({
name: 'xuxi',
age: 18,
})
})
$.get() 和 $.post()
作用:$.get() 方法用于发送get方法; $.post() 方法用于发送post方法
// 客户端
<script>
$('#btn').on('click', function() {
// $.get('/base', {
// name: 'zhangsan',
// age: '18'
// }, function(response) {
// console.log(response)
// })
$.post('/base', function(response) {
console.log(response)
})
})
</script>
// 服务器端
app.get('/base', (req, res) => {
res.send(req.query)
})
app.post('/base', (req, res) => {
res.send({ name: 'xuxi' })
})
jquery中Ajax全局事件 ajaxStart,ajaxComplete
只要页面中有ajax请求被发送,对应的全局事件就会被触发
// 当页面中有ajax请求发送时触发
$(document).on('ajaxStart',function(){
console.log('start');
})
// 当页面中有ajax请求完成时触发
$(document).on('ajaxComplete',function(){
console.log('complete');
}))
NProgress 插件,使用逼真的涓流动画来告诉用户正在发生的事情。
// 1.引入插件的css文件
// 2.引入插件的js文件
// 3.开始调用
// 当页面中有ajax请求发送时触发
$(document).on('ajaxStart',function(){
NProgress.start()
})
// 当页面中有ajax请求完成时触发
$(document).on('ajaxComplete',function(){
NProgress.done()
}))
**邮箱验证规则** :/^[A-Za-z\d]+([-_ .][A-Za-z\d]+)*@([A-Za-z\d]+[-.])+[A-Za-z\d]{2,4}$/