问题描述
我们公司给office文件加上了权限控制,导致这些文件无法被我们公司那些系统的程序读取,只有在把权限设置成public时才能正确读取。所以我需要实现一个校验功能,在用户上传文件时要能够识别权限是不是public,还得纯前端实现。
解决方法
我的助手ds告诉我,这个叫IRM(信息权限管理),并且提供了一个方案,就是使用jszip这个库去解析docx、pptx、xlsx这些文件,大家可能不知道,这些文件其实都是可以解压缩,只要把后缀一改就行,当然我们使用jszip的时候就不用改文件名后缀了。
具体代码
我这里使用的是cdn引入,大家也可以使用npm安装
- cdn
<script src="https://cdn.jsdelivr.net/npm/jszip@3.10.1/dist/jszip.min.js"></script>
- npm
npm i jszip
接下来我们要做的就很简单了,我们只用使用jszip去尝试解析文件,如果能解析,那就是没设置权限的,不能解析,就是设置了权限的。
这个一个简单的demo.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/jszip@3.10.1/dist/jszip.min.js"></script>
</head>
<body>
<input type="file"/>
</body>
<script>
const jszip = new JSZip();
async function hasIRM(file) {
try {
const arrayBuffer = await file.arrayBuffer();
const zip = await jszip.loadAsync(arrayBuffer);
return false;
} catch (e) {
console.error("解压失败,可能被加密", e);
return true;
}
}
// 上传事件监听
document.querySelector('input[type="file"]').addEventListener('change', async (e) => {
const file = e.target.files[0];
if (file) {
const isIRMProtected = await hasIRM(file);
console.log(`文件受IRM保护: ${isIRMProtected}`);
// 根据结果提示用户或限制上传
}
});
</script>
</html>
需要注意的是,设置了权限的文件其实是可以手动解压的,解压后的结果如下
这是没设置权限的文件解压后的结果
可以发现设置权限的文件有个文件叫EncryptedPackage,这个或许也可以作为判断是否有设置权限的依据,只是不知道为什么jszip无法正确读取并解压。