效果
这个玩意的功能你们在这里自己看吧,我就不写了,对我的键盘友好一点吧(借口,其实懒得写)
代码
JS 代码
var selectedFile; // 用于存储选择的文件
var encodeDecodeResult; // 用于存储编码或解码的结果
function handleFileSelect(files) {
if (files.length > 0) {
selectedFile = files[0];
displaySelectedFileName(selectedFile.name);
}
}
function dropHandler(event) {
event.preventDefault();
handleFileSelect(event.dataTransfer.files);
}
function dragOverHandler(event) {
event.preventDefault();
}
// 编码文本
function encodeText() {
var inputText = document.getElementById("inputText").value;
if (inputText) {
var outputText = encodeUnicode(inputText);
displayOutputText(outputText);
displayResult("编码成功!");
} else {
displayResult("请输入文本!");
}
}
// 辅助encodeText函数,让它使用UTF-8
function encodeUnicode(str) {
// 将字符串转换为UTF-8,然后进行base64编码
var utf8Bytes = new TextEncoder().encode(str);
return btoa(String.fromCharCode.apply(null, utf8Bytes));
}
// 解码文本
function decodeText() {
var inputText = document.getElementById("inputText").value;
if (inputText) {
try {
var outputText = decodeUnicode(inputText); // 使用 decodeUnicode 替换 atob
displayOutputText(outputText);
displayResult("解码成功!");
} catch (e) {
displayResult("解码失败:" + e.message);
}
} else {
displayResult("请输入文本!");
}
}
// 辅助decodeText函数,使用UTF-8
function decodeUnicode(str) {
// 对base64编码的字符串进行解码,然后转换为UTF-8字符串
var bytes = atob(str).split('').map(function (char) {
return char.charCodeAt(0);
});
return new TextDecoder().decode(new Uint8Array(bytes));
}
// 重置
function resetFields() {
document.getElementById("inputText").value = "";
document.getElementById("outputText").value = "";
selectedFile = null;
displaySelectedFileName("");
displayResult("");
encodeDecodeResult = null;
}
// 拷贝
function copyResult() {
var outputText = document.getElementById("outputText");
if (outputText.value) {
outputText.select();
document.execCommand("copy");
displayResult("已复制到剪贴板!");
} else {
displayResult("没有可复制的内容!");
}
}
// 编码文件
function encodeFile() {
if (selectedFile) {
var reader = new FileReader();
reader.onload = function (event) {
handleFileEncoding(event.target.result);
};
reader.readAsDataURL(selectedFile);
} else {
displayResult("请先选择文件!");
}
}
// 辅助encodeFile函数
function handleFileEncoding(dataURL) {
var sizeInBytes = calculateSizeInBytes(dataURL);
var sizeInMB = sizeInBytes / (1024 * 1024);
if (sizeInMB > 1) {
displayResult('编码结果较大,请点击"下载结果"来保存');
} else {
displayOutputText(dataURL);
displayResult('编码完成,请点击"复制"或"下载结果"进行保存');
}
encodeDecodeResult = dataURL;
}
function calculateSizeInBytes(dataURL) {
return (dataURL.length * (3 / 4)) - (dataURL.endsWith("==") ? 2 : dataURL.endsWith("=") ? 1 : 0);
}
// 解码文件
function decodeFile() {
// 检查是否有选择的文件
if (selectedFile) {
var reader = new FileReader();
reader.onload = function (event) {
try {
handleFileDecoding(event.target.result);
} catch (e) {
displayResult("文件解码失败!错误信息: " + e.message);
}
};
reader.readAsText(selectedFile);
} else {
// 如果没有选择的文件,尝试从输入框读取dataURL
var inputText = document.getElementById("inputText").value;
if (inputText) {
try {
handleFileDecoding(inputText);
} catch (e) {
displayResult("解码失败!错误信息: " + e.message);
}
} else {
displayResult("请先选择文件或输入dataURL!");
}
}
}
// 辅助decodeFile
function handleFileDecoding(fileContent) {
if (isDataURL(fileContent)) {
var base64EncodedData = fileContent.split(',')[1];
var mimeType = fileContent.split(',')[0].split(':')[1].split(';')[0];
var byteArray = convertToByteArray(atob(base64EncodedData));
encodeDecodeResult = new Blob([byteArray], { type: mimeType });
displayResult("解码成功!请点击下载结果来保存");
} else {
displayResult("提供的内容不是有效的dataURL!");
}
}
function isDataURL(str) {
return str.startsWith('data:');
}
function convertToByteArray(decodedData) {
var byteNumbers = new Array(decodedData.length);
for (var i = 0; i < decodedData.length; i++) {
byteNumbers[i] = decodedData.charCodeAt(i);
}
return new Uint8Array(byteNumbers);
}
function downloadResult() {
if (encodeDecodeResult) {
var blob = createBlobForDownload();
initiateDownload(blob);
} else {
displayResult("没有可下载的内容!");
}
}
function createBlobForDownload() {
return encodeDecodeResult instanceof Blob ? encodeDecodeResult : new Blob([encodeDecodeResult], { type: "text/plain" });
}
function initiateDownload(blob) {
var link = document.createElement("a");
link.download = determineDownloadFileName(blob);
link.href = URL.createObjectURL(blob);
link.click();
encodeDecodeResult = null;
}
function determineDownloadFileName(blob) {
var fileName = "result";
if (blob.type.startsWith("image/")) {
fileName += "." + blob.type.split('/')[1];
} else if (blob.type === "text/plain") {
fileName += ".txt";
}
return fileName;
}
function displaySelectedFileName(fileName) {
document.getElementById("selectedFile").innerHTML = fileName ? "已选择文件:" + fileName : "";
}
function displayOutputText(text) {
document.getElementById("outputText").value = text;
}
function displayResult(message) {
document.getElementById("result").innerHTML = message;
}
原理
没啥原理,就是利用了atob
和btoa
这俩函数,要是没这俩函数的话就没法做了
函数名
其中有一些没啥用的函数(显示状态、文件名;等等),真正有一些用处的函数就是atob
和btoa
这俩玩意了,不过我在这里只想讲讲这两个函数的命名.
首先,当我不知道这两玩意时,一直以为atob
和btoa
的 b 是 base64.
从上面的理解来看,atob
是编码;btoa
是解码,但是事实完全不同.
实际上,a
指的是 ASCII 编码的字符串;而b
指的是binary
,即“二进制”;
而编码和解码的函数与我上面猜测的相反:atob
是解码,btoa
是编码.
为啥这样起函数名?
由于 base64 编码的发明初衷不像我们想象的那样,用来编码一句话,然后“加密”发给朋友(其实完全没有加密功能,“编码”和“加密”是【不同的】); 而是为了传输二进制数据的.
我们常见的很多文件都是使用“二进制”来存储的,比如:图片文件、压缩文件、音频和视频。
但是,这些二进制的文件很难通过网络传输,因为他们是二进制的;这是就需要 base64 登场了,它将二进制文件编码成一个dataURL,就变成了一个看得见、可编辑的字符串,这样就可以传输了.
至于dataURL是啥,可以看看知乎专栏的这篇文章,我认为讲的比较详细:戳这里
还有一篇 Mozilla 的文档:这里
完整源代码下载
这点玩意根本不入各位的法眼,放在GitHub就太丢人了,干脆直接在这里下载个zip么得了:
不过,我的下载链接用的也是dataURL,哈哈哈哈哈哈
P.S.:很无聊,所以水一篇。但是我发现我连水一篇都懒的水 :(