表单上传
表单上传
【备注】
知识点:
enctype(encodetype):该属性规定在将表单数据发送到服务器之前如何对其进行编码。
application/x-www-form-urlencoded: 在发送前编码所有字符(默认)
multipart/form-data: 不对字符编码,在使用包含文件上传控件的表单时,必须使用该值。
text/plain: 空格转换为 "+" 加号,但不对特殊字符编码。
重点:
1、请求方式必须是 POST
2、默认是对表单数据以 "application/x-www-form-urlencoded"进行编码。
3、enctype(encodetype): 编码类型
multipart/form-data: 已二进制形式上传文件,支持多种类型的文件上传
application/x-www-form-urlencoded: 只能上传文本格式文件
缺点:
1、表单提交属于同步提交,提交后整个页面都会发生跳转,用户体验很差。
2、页面之前的状态和数据都会丢失。
解决办法:采用异步上传。
2、异步上传(formData)
formData上传
formData上传
【备注】
知识点:
1、FormData 接口 是 XMLHttpRequest Level2 新加的接口。它提供了一种表单数据的键值对 key/value 的构 造方法,并且可以轻松的将数据通过 XMLHttpRequest.send() 方法发送出去。
2、XMLHttpRequest(XHR) 对象用于与服务器交互。通过 XMLHttpRequest 可以在不刷新页面的情况下请求特定 的 URL,获取数据。这允许网页在不影响用户 *** 作的情况下,更新页面的局部内容。
3、file 是文件接口,它提供了有关文件的信息,并允许网页中 JS 访问其内容。
重点:
1、formData 对象用以将数据编译成键值对,以便用 XMLHttpRequest 来发送数据。
2、formData 对象附加的文件可以是 file 类型 和 Blob 类型。
3、file 对象是特殊类型的 Blob,且可以用在任意的 Blob 类型的 context 中。
4、Blob 对象表示一个不可变、原始数据的类文件对象。它的数据可以按文本或二进制的格式进行读取,也可以转换成 ReadableStream(二进制流)来用于 *** 作数据。
5、在 formData 上传文件时,上传参数数据类型会影响请求头部 content-type 的值,所以不必设置 content- type 的值,浏览器会根据文件类型自动配置。
拓展:
目前,FromData 基本上满足我们的上传需求,但是当文件比较大时,普通的上传方式就会出现一些问题:
1、文件上传超时。
2、文件上传大小超限。
3、上传耗时久。
4、其它网络原因导致上传失败,且失败后需要从头开始。
解决办法:大文件上传。
3、大文件上传
通用解决方案:切片上传 + 秒传
切片上传:
是指将一个大文件切割为若干个小文件,分为多个请求依次上传,后台再将文件碎片拼接为一个完整的文件,即使 某个碎片上传失败,也不会影响其它文件碎片,只需要重新上传失败的部分就可以了。优点是多个请求一起发送文件, 提高了传输速度的上限。
秒传:
是指将文件再传输之前计算其内容的散列值,也就是 Hash 值,将该值传到后台,如果后台存在 Hash 值一致的文 件,认为该文件上传完成。
【文件切片】
切片上传
切片上传
【文件合并】
// 接收切片信息接口
router.post('/upload3', upload.single('file'), function (req, res, next) {
console.log(req.body)
// 接受图片唯一标识符号
let imgname = req.body.uuidfolder;
// 接受切片索引
let imgorder = req.body.imgorder;
// 建立图片存储目录
let imgpath = path.join(__dirname,'..','public/mult',imgname);
// 判断目录是否存在,存在的话直接使用并存储切片,不存在的话就新建。
if (fs.existsSync(imgpath)) {
fs.readFile(req.file.path, function (err, data) {
fs.writeFile(path.join(imgpath, imgorder), data, (err) => {
if (!err) {
res.send("写入后面的文件")
}
})
})
} else {
fs.mkdirSync(imgpath);
fs.readFile(req.file.path, function (err, data) {
fs.writeFile(path.join(imgpath, imgorder), data, (err) => {
if (!err) {
res.send("第一次写入并新建文件夹")
}
})
})
}
})
// 合并图片接口:
router.post('/merge',function(req,res){
let id = req.body.id;
let folderpath = path.join(__dirname,"..",'public/mult',id);
let destinpath = path.join(__dirname,"..",'public/img',id+'.jpg');
let dist = '/img/'+id+'.jpg'
fs.readdir(folderpath,function(err,arr){
let arr2 = arr.map(e=>path.join(folderpath,e));
concat(arr2, destinpath, function(err) {
if (err) throw err
res.send(dist);
});
})
})
// 注意:
1、后端根据唯一标识符和切片下标来拼接文件。
2、后端可以将接收和合并拆成两个接口来供前端调用,这样做的优点是节省服务端性能。
缺点:
切片上传时并不能保证每个请求条件都成功,有可能因为各种原因导致部分切片丢失
4、大文件断点续传
断点续传
断点续传
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)