下载文档
我们查柜的认知是后端给前端传一个链接地址,将地址放在a标签上,点击链接下载文件。
可有时候往往不是这样的,后端给前端返回了一个文档流,这就需要我们自己转换为Blob格式的数据,再使用这个数据转化成一个url地址,模拟一个a标签,将地址放进去。
//创建一个blob是excel格式的
let blob = new Blob([res.data], {
type: 'application/vnd.ms-excel'
});
let contentDisposition = res.headers['content-disposition'];
//国际化默认名称
let fileName = langUtil.t(
defineMessages({
v: { id: 'dynamicForm.export.excelName', defaultMessage: '表格数据' }
})
)+"_"+moment(new Date()).format("YYYY-MM-DD");
//根据后端返回res.headers['content-disposition'];格式,取文件名
if (contentDisposition) {
fileName = window.decodeURI(
(contentDisposition.split(';')[1] || '').split('=')[1],
'UTF-8'
);
}
//createObjectURL创建一个地址
let downloadUrl = URL.createObjectURL(blob);
//创建a标签,赋值地址
let downloadLink = document.createElement('a');
downloadLink.style.display = 'none';
downloadLink.href = downloadUrl;
//设置下载的属性
downloadLink.setAttribute('download', fileName);
document.body.appendChild(downloadLink);
//模拟点击
downloadLink.click();
如何在只有图片url的情况下,上传文件
下面是前两年有个需求,当时写了下相关说明文档
https://shimo.im/docs/wRrcpkTJkqcqpqX6/ 《记图片地址转文件并上传的一次操作》,可复制链接后用石墨文档 App 或小程序打开
简单概括一下我们的需求:我们要在点击图片之后,调用另一个接口,把该张图片文件上传上去。
点击这张图片,我们只能拿到一个url
//这是我们能拿到的图片地址
var img =
"http://dumbo-daily.oss-cn-shanghai.aliyuncs.com/images/80146/29968540-2d52-11ea-9da8-9d82bfa55a03.png?OSSAccessKeyId=LTAI4FuYJmVdizPfGGW3TjnH&Expires=15779641503600&Signature=E0oIN1zu0%2Ff%2B%2BsA1p2G2jvrjRiI%3D";
//我们创建一个图片,将图片地址赋给图片
var image = new Image();
image.src = img;
image.setAttribute("crossOrigin", "Anonymous");
image.onload = function() {
//等到图片加载完成之后,将图片转成base64
var base64 = getBase64Image(image);
console.log(base64);
//将base64转换成file
var file = btof(base64, "test");
//拿到file,用file上传文件
};
//下面是分别使用的两个方法
//将图片转换成base64
function getBase64Image(img) {
//先将图片转换成canvas,并绘制canvas
var canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, img.width, img.height);
var ext = img.src.substring(img.src.lastIndexOf(".") + 1).toLowerCase();
//使用canvas的toDataUrl,将canvas转换成base64数据
var dataURL = canvas.toDataURL("image/" + ext);
return dataURL;
}
//转换成file
function btof(data, fileName) {
const dataArr = data.split(",");
//处理base64 数据
//因为图片的base64大概是这样的 :base64,R0lGODlhHAAmAKIHAKqqqsvLy0hISObm5vf394uLiwAAAP///yH5B…EoqQqJKAIBaQOVKHAXr3t7txgBjboSvB8EpLoFZywOAo3LFE5lYs/QW9LT1TRk1V7S2xYJADs=
//所以要将数据截取一下
const byteString = atob(dataArr[1]);
const options = {
type: "image/jpeg",
endings: "native"
};
// 创建一个8位无符号整型数组,将byteString的每个字节转换成unicode变化后,放进这个整型数组
const u8Arr = new Uint8Array(byteString.length);
for (let i = 0; i < byteString.length; i++) {
u8Arr[i] = byteString.charCodeAt(i);
}
//然后就可以根据数组创建文件了
return new File([u8Arr], fileName + ".jpg", options);
}
关于btoa和atob
btoa从String 对象中创建一个 base-64 编码的 ASCII 字符串,其中字符串中的每个字符都被视为一个二进制数据字节
atob 将base64解码,还原成编码前的数据
其实这两个方法特别好记,拆开看就是 b to a ,以及 a to b
const encodedData = btoa(‘Hello, world’); // encode a string
const decodedData = atob(encodedData); // decode the string
Uint8Array 数组类型表示一个8位无符号整型数组,创建时内容被初始化为0。创建完后,可以以对象的方式或使用数组下标索引的方式引用数组中的元素。
new Uint8Array(); // ES2017 最新语法
new Uint8Array(length); // 创建初始化为0的,包含length个元素的无符号整型数组
new Uint8Array(typedArray);
new Uint8Array(object);
new Uint8Array(buffer [, byteOffset [, length]]);
str.charCodeAt(index) 是将这个字符串的某一位,转化成Unicode 16位整数
而charAt([index])是直接返回该字符串index处的字符
关于unicode,看看他人的文章 https://blog.csdn.net/hezh1994/article/details/78899683
方法二
getBase64(imgUrl,_this) {
window.URL = window.URL || window.webkitURL;
const xhr = new XMLHttpRequest();
xhr.open("get", imgUrl, true);
// 至关重要
xhr.responseType = "blob";
xhr.onload =function() {
if (this.status == 200) {
// 得到一个blob对象
const blob1 = this.response;
// const file = new File([blob], 'test.png', {type: 'image/png'});
// 至关重要
const oFileReader = new FileReader();
oFileReader.onloadend = (e)=> {
const base64 = e.target.result;
//拿到base64
console.log(blob,file)
};
oFileReader.readAsDataURL(blob1);
//====为了在页面显示图片,可以删除====
var img = document.createElement("img");
img.onload = function (e) {
window.URL.revokeObjectURL(img.src); // 清除释放 };
// 创建DOMString
let src = window.URL.createObjectURL(blob);
img.src = src
document.getElementById("container1").appendChild(img);
//====为了在页面显示图片,可以删除====
}
}
xhr.send();
}
粘贴上传
主要原理是监听粘贴parse事件
document.addEventListener('paste', function (event) {
var items = event.clipboardData && event.clipboardData.items;
var file = null;
if (items && items.length) {
// 检索剪切板items
for (var i = 0; i < items.length; i++) {
if (items[i].type.indexOf('image') !== -1) {
file = items[i].getAsFile();
break;
}
}
}
// 此时file就是剪切板中的图片文件
});
预览上传的图片
var reader = new FileReader()
reader.onload = function(event) {
// event.target.result就是图片的Base64地址啦
}
reader.readAsDataURL(file);
上面代码中的event.target.result就是图片的Base64地址,然后页面对应DOM元素位置插入如下HTML就可以看到图片效果了:
< img src="’ + event.target.result + '"/>