1.上传方案
1、上传文件流到数据库
2、上传base64或者blob到数据库
3、当图片很多的时间,需要建立一个图片库,专门保存图片。然后将图片路径存到数据库
- 前两种方法当你的图片太大的话就不适用了。我用的是在前台将图片转换为base64然后传到后台保存导数据库,这样下次直接取出来放到src属性中就可以显示图片了。第三种方式其实应该是很常用。
2.涉及需要掌握的点
1、Blob
- 1、Blob,Binary Large Object的缩写,代表二进制类型的大对象。在Web中,Blob类型的对象表示不可变的类似文件对象的原始数据,Blob对象即是类似文件对象的二进制数据。
2、base64编码
- 1、简单来说,任何一个数据无非可以看作一个比特流,如01000100010......那么我们取6个比特为一组,计算它的ascii值,得到一个字符,这个字符肯定是可见字符,好,把它对应的字符写出来,再取6个比特,计算...,如此下去,直到最后,就完成了base64编码。
- 2、Base64编码的主要的作用不在于保证二进制数据的安全,而在于让内容能在各个网关间无错的传输,这才是Base64编码的核心作用。(在计算机中任何数据都是按ascii码存储的,而ascii码的128~255之间的值是不可见字符。而在网络上交换数据时,比如说从A地传到B地,往往要经过多个路由设备,由于不同的设备对字符的处理方式有一些不同,这样那些不可见字符就有可能被处理错误,这是不利于传输的。所以就先把数据先做一个Base64编码,统统变成可见字符,这样出错的可能性就大降低了。)
- 3、有些图片src采用Base64编码不仅比较简短,同时也具有不可读性,即所编码的数据不会被人用肉眼所直接看到。还有减少http请求。
- 1、上传了一个二进制文件,即上传文件流到服务端处理。
4、上传图片预览
- file按钮上传文件,点击确定马上就能看到预览的效果,但无论怎样都取不到file上图片的真实路径,得到的反而是C:\fakepath\a.jpg,这个路径是错误的。浏览器基于保护用户的相关安全措施,隐藏了上传的真实路径,用fakepath代替。
- 方法1:FileReader。readAsDataURL读取为 DataURL。
- 方法2:URL.createObjectURL(blob)。
- 方法3: 用上传到cdn服务器的地址。
5、Blob URL和Data URL
-
Blob URL是blob协议的URL,它的格式如下:blob:http://XXX。
-
常见的场景有:作为文件的下载地址和作为图片资源地址。
-
下载地址:
var link = document.getElementsByTagName("a")[0]; link.download = "file"; link.href = URL.createObjectURL(blob); //点击a标签就可以下载了
-
图片资源地址
var file = e.files[0]; var blob = URL.createObjectURL(file); var img = document.getElementsByTagName("img")[0]; img.src = blob; img.onload = function(e) { URL.revokeObjectURL(this.src); // 释放createObjectURL创建的对象## }
-
Blob URL和Data URL区别
- 1、Blob URL的长度一般比较短,但Data URL因为直接存储图片base64编码后的数据,往往很长,浏览器在显示Data URL时使用了省略号(…)。当显式大图片时,使用Blob URL能获取更好的可能性。
- 2、Blob URL 只能在当前应用内部使用,把Blob URL复制到浏览器的地址栏中,是无法获取数据的。Data URL相比之下,就有很好的移植性,你可以在任意浏览器中使用。
- 3、除了可以用作图片资源的网络地址,Blob URL也可以用作其他资源的网络地址,例如html文件、json文件等,为了保证浏览器能正确的解析Blob URL返回的文件类型,需要在创建Blob对象时指定相应的type。
// 创建HTML文件的Blob URL var data = "<div style='color:red;'>This is a blob</div>"; var blob = new Blob([data], { type: 'text/html' }); var blobURL = URL.createObjectURL(blob); // 创建JSON文件的Blob URL var data = { "name": "abc" }; var blob = new Blob([JSON.stringify(data)], { type: 'application/json' }); var blobURL = URL.createObjectURL(blob);
- 4、Blob URL可以方便的使用XMLHttpRequest获取源数据,对于Data URL,并不是所有浏览器都支持通过XMLHttpRequest获取源数据的。
var blobUrl = URL.createObjectURL(new Blob(['Test'], {type: 'text/plain'})); var x = new XMLHttpRequest(); // 如果设置x.responseType = 'blob',将返回一个Blob对象,而不是文本: x.onload = function() { alert(x.responseText); // 弹出 Test }; console.log(blobUrl) x.open('get', blobUrl); x.send();
3.项目中需要考虑的技术埋点
问题1: html自带file控件样式丑陋,如何达到UI设计要求效果;
btn.onclick = function() {
file.click() // 调取系统选择图片的弹框
}
问题2: 选择图片后,按照一定的样式回显示图片如何实现;
FileReader对象的readAsDataURL方法可以将读取到的文件编码成Data URL。Data URL是一项特殊的技术,可以将资料(例如图片)内嵌在网页之中,不用放到外部文件。使用Data URL的好处是,您不需要额外再发出一个HTTP 请求到服务器端取得额外的资料;而缺点便是,网页的大小可能会变大。它适合应用在内嵌小图片,不建议将大图像文件编码成Data URL来使用。您的图像文件不能够超过浏览器限定的大小,否则无法读取图像文件。
function previewImg(){
let preview = document.querySelector('img[id=preview]');
let file = document.querySelector('input[id=file]').files[0];
let reader = new FileReader();
reader.onloadend = function () {
preview.src = reader.result;
}
if (file) {
reader.readAsDataURL(file);
} else {
preview.src = "";
}
}
问题3: 无刷新提交,采用原始的ajax提交
1)let request = new XMLHttpRequest()
2)request.open("POST", url)
3)request.onload = function(oEvent) {
if (request.status == 200) {
//alert(“success”);
} else {
//alert(“出错啦!请稍后再试。” + request.status);
}
};
4) request.send(formData);
问题4: 序列化(serialize())表单是无法序列化二进制数据的,该如何提交文件类型?
故我们采用FormData的方式提交文件类型。
问题5: JS选择器获取单个文件、“multiple”类型多文件及非“multiple”类型的多个同类型input控件文件;
1)单个文件;
document.querySelector('input[id="file"]').files[0];
2)若是“multiple”类型的input控件,即一个input控件可以同时选择多个文件(<input type=”file” multiple=”multiple” />);
document.querySelector('input[id="file"]').files;
document.querySelector('input[id="file"]').files.length;
- 我们考虑下另外一种方式,采用追加的方式实现多图预览,譬如有多个id同为file的input组件,且全是单选,这些照片为一组,需要统一获取并上传;
let files = document.querySelectorAll('input[id="file"]');
let formData = new FormData();
for(let i=0;i<files.length;i++){
//将一组文件类型追加至file集合中
//这样即可将一组文件加入FormData的同一key下,一同提交。
formData.append("file",files[i].files[0]);
}
问题6:File API
1)File - 独立文件;提供只读信息,例如名称、文件大小、mimetype 和对文件句柄的引用。
2)FileList - File 对象的类数组序列(多文件上传)。
3)Blob - 可将文件分割为字节范围。
4)FileReader - 读取File或Blob
2)// 检测是否支持File API
if (window.File && window.FileReader && window.FileList && window.Blob) {
// 支持
} else {
alert('不支持');
}
问题7:FileReader就是html5为我们提供的读取文件的api。它的作用就是把文本流按指定格式读取到缓存,以供js调用。
1)FileReader有四种读取文件的方式:
- 1.readAsBinaryString读取为二进制码
- 2.readAsDataURL读取为 DataURL
- 3.readAsText读取为文本
- 4.readAsArrayBuffer
2)DataURL有其固定的格式,如下:data:[文件格式];base64,[文本流base64编码]。 、举个例子: •jpg格式: data:image/jpeg;base64,/9j/4...
问题8:URL.createObjectURL(blob)
1)方法会创建一个参数中给出的对象的URL。
2)参数blob是用来创建 URL 的File对象和Blob对象。
3)oPreview.src = window.URL.createObjectURL(oFile);
console.log(window.URL.createObjectURL(oFile));
"blob:http://null.jsbin.com/2099b053-bbd4-4e46-864d-9b2b0abc09e6"
参考
详解Blob
Base64 的原理、实现及应用
FileReader以及URL.createObjectURL(blob)上传图片预览代码实现
网友评论