一、后端返回二进制流图片问题。
背景
前段时间研究二进制流图片展示遇到了Blob对象,在这里做一下笔记。
content-type: application/octet-stream 二进制数据。
Blob
Binary Large Object的缩写,代表二进制类型的大对象。Blob的存在,允许我们可以通过JS直接操作二进制数据。
blob方法直接操作二进制数据。
通过url下载文件
Blob URL是blob协议得URL,它的格式如下:
blob:http://xxx
Blob URL可以通过URL.createObjectURL(blob)创建。常见得场景有: 作为文件得下载地址和作为图片资源地址。
- 会产生一个类似 blob:d3958f5c-0777-0845-9dcf-2cb28783acaf 这样的URL字符串
- 你可以像使用普通 URL 那样使用它,比如用在 img.src 上。
在每次调用createObjectURL()方法时,都会创建一个新的URL对象.
//axios需要添加responseType:'blob'
var data = "<div style='color:red;'This is a blob</div>";
var blob = new Blob([data], {type: 'text/html'}); // 创建Blob对象
console.log(blob); // Blob {size: 43, type: "text/html"}
var blobUrl = URL.createObjectURL(blob);
console.log(blobUrl); // blob:http://localhost:63342/bd736211-1897-402c-a8da-e4f5037fef7f
优化:
URL.revokeObjectURL()方法会释放一个通过URL.createObjectURL()创建的对象URL。资源加载完后,不需要再次加载时,可以通过这个方法进行释放。
二、二进制流图片的下载
问题一:如果后端返回二进制流格式的图片,前端如何去下载呢。
- a标签的href就可以解决,因为浏览器不认识二进制流,使得图片就下载了。
问题二:但是下载的文件名字是url的名字,如何解决这个问题。
- 可以使用download属性,但是download属性在跨域时是无效的。
- 解决方案时:ajax请求服务,下载到本地,这样download属性就起作用了。
utils.forceDownload = (url, filename) => {
if (!filename) {
filename = url.split('\').pop().split('/').pop().replace(/?.*$/, '');
}
fetch(url, {
headers: new Headers({
'Origin': location.origin
}),
mode: 'cors' // 跨域访问
}).then(response => response.blob()) // 将资源下载的到本地了。response 是乱码的流,blob()解决乱码流的问题。
.then(blob => {
const blobUrl = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.download = filename;
a.href = blobUrl;
a.click();
}).catch(e => {
console.log(e)
});
};
三、普通图片的下载
问题一:后端返回的content-type: img/jpg这种图片格式的。
a的href 预览功能,因为浏览器认识它。
想要下载,就强制下载,加download属性,回到上面的问题2。下载到本地加download。
四、代码简化问题带来的思考
if (temp) {
if(temp.totalAmountLimit) {
this.sumPayAmount = temp.totalAmountLimit;
}else {
this.sumPayAmount = '';
}
}
// 上面的代码用下面替换。
this.sumPayAmount = temp && temp.totalAmountLimit || '';
思考: && 与 || 运算符
总的是:短路计算 ,要么返回a,要么返回b,打破了我之前 ture和false的认知。
优先级,&&优先级别大于 || 。