1.重点掌握及知识点
重点掌握:
- XMLHttpRequest对象的使用
- ajax的封装使用
- 利用node搭建服务器提供数据
- FormData对象的使用
- 利用formData实现多文件上传
- qq空间批量上传图片案例
知识点:
- XMLhttpRequet的使用
- 会使用ajax进行数据交互
- 会使用node搭建服务器
- 学会使用FormData来上传文件
1.跨域 : 非同源; 2. 非跨域: 同源;
协议 -- 域名 -- 端口 ; 都相同 同源;(同一个服务器);
如,http(https):// www.kaikeba.com:80/news/index?id=1
localhost / 127.0.0.1;本地 ip
2.ajax封装
封装步骤:
- 使用Object.assign()函数将默认配置和传递配置参数进行合并;
- 传递的method中,需要判断get/post,get传参需要使用queryString即使用?进行拼接url;post也要凭借成参数并通过send()进行传递;
- 封装拼接url方法(Object.keys(obj)和Object.values(obj)),map循环key=value并使用join("&")进行拼接(这种方式如果数据对象为多层数据,需要递归解决);
- onload()方法获取返回数据,xhr.responseText()
- 判断get/post方法,不同请求方式,send()方法不同。
- 需要给出默认headers配置,用户也可以自定义设置,通过for in设置头部setRequestHeader();设置头部后,需要switch判断头部,只有为JSON时,才能以封装的数据格式以post方式传递数据,如果是json格式,需要转为json再发送
- onload()时也需要判断返还数据类型,或者直接使用JSON.parse()直接数据转为对象
封装成类似下面形式:
ajax({
url: "/xml",
method: "post",
data: {
hello: "你好",
height: "178cm"
},
success(res) {
console.log(res)
}
})
ajax.js:
class MyAjax {
constructor(options) {
// 将传入的配置和默认配置进行合并
this.options = this.ajax(options);
}
ajax(options) {
let xhr = new XMLHttpRequest();
// 注意assign()方法是将后面的输入配置合并前面的默认配合(注意需要opts接收后才是合并后的对象)
let opts = Object.assign({
// 因为get/post请求不同带参方式不同,所以需要拼接url
url: '',
method: 'get',
data: '',
headers:{
"content-type":"application/x-www-form-urlencoded",
},
success(res) {}
}, options);
// 判断get请求时拼接url
if (opts.method === "get") {
opts.url = olUrl(opts);
}
// 发送请求
xhr.open(opts.method, opts.url, true);
// 循环设置头部(可能会有不同的头部信息,不只是content-type),注意设置头部必须在open()方法之后
for(let header in opts.headers){
xhr.setRequestHeader(header, opts.headers[header]);
}
// 根据不同头部信息,发送请求不同
let sendData;
switch(opts.headers['content-type']){
// 如果请求头content-type为application/x-www-form-urlencoded直接拼接参数
case 'application/x-www-form-urlencoded':
sendData = olUrl(opts);
break;
case 'application/json':
sendData = JSON.stringify(opts.data);
break;
}
// 获取返回数据(需要设置到options中的success,在调用时才能使用success()获得返回数据)
xhr.onload = function(){
// 用户名密码都正确时会返回页面
if(xhr.responseText.startsWith("<!DOCTYPE html>")){
opts.success({
msg:"校验成功",
code:4
});
}else{
opts.success(JSON.parse(xhr.responseText));//返回数据全部转为对象
}
}
// 判断如果是post请求需要将请求数据一并发送
if (opts.method === "get") {
xhr.send();
} else {
xhr.send(sendData);
}
// 拼接url(只有get请求需要拼接)
function olUrl(options) {
let keys = Object.keys(options.data);
let values = Object.values(options.data);
let queryString = keys.map((key, index) => {
return key + '=' + values[index];
}).join("&");
return options.url + "?" + queryString;
}
}
}
// 通过定义函数new MyAjax(options),返回MyAjax对象
function ajax(options) {
return new MyAjax(options);
}
export default ajax;
3.通过formData实现《qq空间批量上传图片》
-
需求确定:相册内容显示相册
-
nodejs搭建后台
-
分析上传元素
-
登录区分不同用户
-
创建上传对象
-
上传图片
-
获取上传后的最新图片数据
-
3.1需求确定
3.1.1相册内容显示相册
点击上传(可选择多张图片),上传成功后,会显示相册图片;
上传时,有上传进度显示
3.2nodejs搭建后台
使用nunjucks加载页面
3.3分析上传元素
3.3.1登录区分不同用户
3.3.2创建上传对象
- 上传图片可以有多张图片:input中使用multiple="multiple"即可选择多张上传图片;
- 获取并显示待上传图片:通过原生this.files可以获取所有图片对象。根据文件对象循环创建HTML(createElement("div"))放入对应容器中;
- 通过FileReader读取上传文件。let fileReader = new FileReader(file);fileReader.readAsDataURL(file);fileReader.onload()时将图片转为base64,并将base64作为临时路径(即在onload时再创建HTML);
- 继续添加时,继续创建HTML;
3.3.3上传图片
- 上传:监控上传进度,后台转存;此处上传是一个接一个进行上传,将需要上传时将html中对象一个一个添加到数组中,上传时将每个图片抽象成图片类(每张图片都有自己的创建HTML,监控上传进度,上传等方法);
- 将创建的节点进行保存,用于监控上传进度;
- 通过FormData进行上传
- 通过unload中的onprogress监控上传进度,onload()处理上传成功后的处理;
- 点击上传时,遍历存储的图片数组,并进行上传
- 使用Promise监控一个一个上传:调用时返回Promise对象,在每一个上传的函数中,使用async await处理即可
3.3.4获取上传后的最新图片数据
3.4完整案例展示
4.总结
- XMLHttpRequest对象的使用
- ajax的封装使用
- 利用node搭建服务器提供数据
- FormData对象的使用
- 利用formData实现多文件上传
- 通过async和await处理异步
- qq空间批量上传图片案例