ajax
应用场景
- 下拉加载更多数据
- 列表数据无刷新分页
- 表单项离开焦点数据验证
- 搜索框下拉列表提示
运行原理
Ajax 相当于浏览器发送请求与接收响应的代理人,以实现在不影响用户浏览页面的情况下,局部更新页面数据,从而提高用户体验
实现步骤
1.创建 ajax 对象
var xhr = new XMLHttpRequest();
2.告诉 ajax 对象请求地址以及请求方式
xhr.open('get', 'http://loaclhost:3000/get');
xhr.open('post', 'http://loaclhost:3000/post');
3.发送请求
get方式
xhr.send();
post方式
xhr.setRequestHeader('Content-Type', 'application/json') //post方式必须设置
xhr.send(JSON.stirngify({name:zhangsan,age:20})); //send不能直接传输json对象,要转换成字符串
请求参数格式 application/x-www-form-urlencoded application/json
传统网站默认的表单post提交方式,数据格式是application/x-www-form-urlencoded
// 传输json对象,服务端更改配置 app.use(bodyParser.json())
4.获取服务器端给与客户端的响应数据
xhr.onload = function () {
console.log(xhr.responseText); // 服务端返回的数据xhr.responseText
}
ajax 状态码,事件
0:请求未初始化(还没有调用open())
1:请求已经建立,但是还没有发送(还没有调用send())
2:请求已经发送
3:请求正在处理中,通常响应中已经有部分数据可以用了
4:响应已经完成,可以获取并使用服务器的响应了
xhr.readyState // 获取Ajax状态码
xhr.status //获取http状态码
xhr.onreadystatechange 事件
当状态码为 4 时就可以通过 xhr.responseText 获取服务器端的响应数据了
为什么使用onreadystatechange事件?onload事件在低版本ie浏览器不兼容,另外onload事件调用次数为1次
xhr.getResponseHeader('键名') // 获取响应头信息
xhr.upload.onprogress = function(e){
e.loaded // 文件已经上传多少
e.total // 文件总大小
} // 文件上传事件过程中持续触发
// 所以可以获得百分比percent = (e.loaded/e.total*100).toFixed(2) + '%'
低版本 IE 浏览器的缓存问题
xhr.open('get', 'http://www.example.com?t=' + Math.random());
要使每一次请求中的请求参数的值不相同
ajax封装
原理:
1.使用一个default对象,存储需要的各个参数,放入ajax方法中运行
2.需要一个对象传参,这个对象覆盖default对象 使用Obeject.assign(default,options)覆盖
ajax编程扩展
非服务器端使用模板引擎 art-template
1.下载 art-template 模板引擎库文件并在 HTML 页面中引入库文件
<script src="./js/template-web.js"></script>
2.准备 art-template 模板 是html文件中的一个片段,用script标签包裹
<script id="tpl" type="text/html"> //设置好id type
<div class="box"></div>
</script>
3.告诉模板引擎将哪一个模板和哪个数据进行拼接 全局环境下多了个template方法
var html = template('tpl', {uid:'001',username: 'zhangsan', age: '20'});
4.将拼接好的html字符串添加到页面中
document.getElementById('container').innerHTML = html;
5.通过模板语法告诉模板引擎,数据和html字符串要如何拼接
<script id="tpl" type="text/html">
<div class="box" id={{uid}}> {{ username }} </div>
</script>
FormData对象使用
作用
模拟HTML表单,相当于将HTML表单映射成表单对象,自动将表单对象中的数据拼接成请求参数的格式
异步上传二进制文件
-
使用方式
// 将表单转化为 formData 对象
var form = document.getElementById(‘form’);
var formData = new FormData(form);
// 提交表单对象
xhr.send(formData);// 或者直接创建对象
var formData = new FormDate()
formData.append(属性名,属性值)
// 再利用xhr上传注意事项
1.Formdata 对象不能用于get请求
2.bodyParser 模块不能解析formData对象表单数据,需要使用 formidable 模块进行解析(后端node) -
FormData 对象的实例方法
formData.get(‘key’);
formData.set(‘key’, ‘value’);
formData.delete(‘key’);
formData.append(‘key’, ‘value’);
// set和append都可以追加属性值,set会覆盖 append会保留同名原属性和值 -
二进制文件上传
客户端上传文件
// onchange事件 创建空表单对象
var formData = new FormData();
// 将用户选择的二进制文件追加到表单对象中
formData.append(‘attrName’, this.files[0]);//文件是一个集合
// 配置ajax对象,请求方式必须为post
xhr.open(‘post’, ‘提交地址’);
xhr.send(formData);node服务端实现文件上传路由
//创建formidable表单解析对象
const form=new formidable.IncomingForm();
//设置客户端上传文件的绝对路径
form.uploadDir=path.join(__dirname,‘public’,‘uploads’);
//保留后缀
form.keepExtensions=true;
form.parse(req,(err,fields,files)=>{ // 错误对象 普通字段 文件
log(files.attrName.path)// 文件存储的路径
res.send(‘ok’)
}) -
上传图片即时预览
1.返回上传的图片存储地址,创建img标签,赋值src属性,onload事件向容器内追加创建的img元素
2.同步方法:window.URL.createObjectURL(file)取当前文件的一个内存URL,不使用的时候就revokeObjectURL(),也会随document的卸载而销毁,性能比3好点
3.异步方法:FileReader.readAsDataURL(file)获取一段data:base64的字符串
同源策略***
- 同源 协议/域名/端口都要相同,有一个不同就不是同源
使用jsonp解决同源限制问题
原理:绕过同源策略影响,使用src的请求,利用函数获得数据
1.把不同源的服务器端请求地址写在script标签的src属性中
2.服务器端响应数据必须是一个函数的调用,真正要发送给客户端的数据需要作为函数调用的参数
3.在客户端全局作用域下定义函数 fn(data){log(data)} 定义在script标签前面
4.服务器端返回函数的调用 res.send(fn(实际数据)) 因为写在了script标签中,会被当做js代码执行
JSONP代码优化
变成动态请求:
客户端:1.创建script标签 2.设置src属性(带着函数名去 ?callback=fn) 3.script标签追加到页面中 4.script标签onload后,再删除script标签
服务端:1.获取传来的函数名称 res.query.callback 2.拼接字符串,返回函数调用
封装jsonp函数
客户端:
1.动态创建script标签->添加src属性->appendChild->script的onload事件再removeChild
2.随机生成函数名 fnName = 'jsonp'+Math.random().toString().replace('.','');
3.方法挂载到window对象上 window[fnName] = options.success
4.?如果有多个参数,循环options.data 拼接成&key=value
服务端:
使用express提供的方法,省去拼接字符串,res.jsonp({name:lisi,age:20});
接收函数名称callback的值,将真实数据stringify,拼接字符串返回
客户端跨域配置
vue项目开发中常用两种方式,在vue.config.js中配置,老版本在webpack配置文件配置
1.配置poxy
2.配置接口代理时候使用axios等直接请求网络上数据
before(app){...}
CORS跨域资源共享
node服务器端配置:Access-Control-Access-Origin
express中配置
res.header(' Access-Control-Allow-Origin','*'); //允许哪些客户端访问自己
res.header(' Access-Control-Allow-Mehods','get,post'); //允许客户端使用哪些请求方法访问自己
简单的方式可以直接使用cros第三方模块
服务器端访问不同源网站
使用第三方模块request axios等
-
Ajax技术发送跨域请求时,默认情况下不会在请求中携带cookie信息
//如果要携带cookie信息,需要配置
//客户端ajax对象设置跨域请求时是否携带cookie信息
xhr.withCredentials = true 默认为false
//服务端响应头设置允许客户端发送请求时携带cookie
Access-Control-Allow-Credentials:true
jQuery中的ajax方法
-
$.ajax()
$.ajax({
type: ‘post’,
url: ‘http://www.example.com/index’, // 如果协议域名端口相同,可以省略
data: { name: ‘zhangsan’, age: ‘20’ }, / JSON.stringify(params)
contentType: ‘application/x-www-form-urlencoded’, / application/json
beforeSend: function () { // 请求发送之前调用
return false
},
processData: true, // 解析data 如果是上传二进制文件,设置为false,不要解析,同时设置contentType为false
success: function (response) {},
error: function (xhr) {}
}); -
serialize()方法 将表单中的数据自动拼接成字符串类型的参数
-
serializeObject()方法 将表单中的数据转换为对象类型,自己封装,利用jQuery中的serializeArray()方法
-
$.ajax()方法可以发送JSONP请求 (JSONP请求本身就属于get请求)
$.ajax({
url: ‘…’,
dataType: ‘jsonp’,
jsonp:‘cb’, // 可选参数,修改callback参数名称
jsonCallback:‘fnname’, // 可选参数 指定函数名称
success: function (response) {},
error: function (xhr) {}
}); -
$.get(url请求地址,{对象},function(response){…})
-
$.post(url请求地址,{对象},function(response){…})
-
Ajax全局事件
- .ajaxStart() //当请求开始发送触发
- .ajaxComplete() //当请求完成触发 $(document).on(‘ajaxstart’,function(){…})
-
NProgress插件 //进度条
RESTful风格的API
-
RESTful API实现
express中使用
app.get(’/users’,(req,res)=>{})
app.get(’/users/:id’,(req,res)=>{
const id = req.params.id; //获取客户端传递过来的用户id
})
XML 可扩展标记语言(了解即可)
-
XML DOM
服务器端要指定类型 res.header(‘content-type’,‘text/xml’);
xhr.responseXml获取服务器端返回的XML数据
对象方法
getElementByTagName()
getElementById()