又遇到了一件鬼打墙的事,欲哭无泪。
1
几天前,有个bug:blob文件下载,如果下载非txt文件,比如图片、xlsx,下载后的文件无法正确显示。
// 下载文件
async download(row, prop) {
const res = await resourceDownload(row[prop.field + "fileId"]);
// res 为 blob 类型
const blob = new Blob([res], { type: "text/plain;charset=utf-8" });
this.$download.saveAs(blob, row[prop.field]);
},
于是根据文件类型设置了不同的 mime type,就可以正常显示下载的文件了。
// 下载文件
async download(row, prop) {
const { id, type, name } = row[prop.field];
switch (type) {
case "jpg":
this.blobType = "image/jpeg";
break;
case "png":
this.blobType = "image/png";
break;
case "xlsx":
this.blobType =
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
break;
case "txt":
this.blobType = "text/plain;charset=utf-8";
break;
}
const res = await resourceDownload(id);
// res 为 blob 类型
const blob = new Blob([res], {
type: this.blobType,
});
this.$download.saveAs(blob, name);
},
2
但是今天接到新需求,如果下载 json 文件,下载后还是无法正确显示。如果手动把 json 的 mime type 加上,这样每次新增其他类型的文件,就要手动修改代码,太过麻烦,需要一个一劳永逸的办法。
// 下载文件
async download(row, prop) {
const { id, type, name } = row[prop.field];
switch (type) {
// 新增 json
case "json":
this.blobType = "application/json";
break;
case "jpg":
this.blobType = "image/jpeg";
break;
case "png":
this.blobType = "image/png";
break;
case "xlsx":
this.blobType =
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
break;
case "txt":
this.blobType = "text/plain;charset=utf-8";
break;
}
const res = await resourceDownload(id);
// res 为 blob 类型
const blob = new Blob([res], {
type: this.blobType,
});
this.$download.saveAs(blob, name);
},
于是发现,对于非txt的文件可以统一设置为 application/octet-stream
, txt文件设置为 text/plain;charset=utf-8
。
// 下载文件
async download(row, prop) {
const { id, type, name } = row[prop.field];
switch (type) {
case "txt":
this.blobType = "text/plain;charset=utf-8";
break;
default:
this.blobType = "application/octet-stream";
break;
}
const res = await resourceDownload(id);
// res 为 blob 类型
const blob = new Blob([res], {
type: this.blobType,
});
this.$download.saveAs(blob, name);
},
但是测试时发现,txt 文件设置为 application/octet-stream
也能正确下载显示;甚至不设置 type 也能正确下载显示任何类型的文件。
// 下载文件
async download(row, prop) {
const { id, name } = row[prop.field];
const res = await resourceDownload(id);
// res 为 blob 类型
const blob = new Blob([res]);
this.$download.saveAs(blob, name);
},
真的是芭比Q了。陷入了鬼打墙。
我知道肯定是哪里出了问题,要么是测试时没有遵循 "同一对象原则",要么是记忆出现了混乱。