IE 共享违例 踩坑记

最近在生产上遇到一个问题,就是通过IE上传xml文件之后,使用某些软件去打开这个文件,会报共享违例错误,导致文件无法打开,但是在Chrome上面是没有这个问题的。一开始以为是js操作文件之后没有切断引用,但是查看代码之后发现最后都是有释放的,而且关闭tab页之后文件就能操作。

一通检查跟思考之后,发现IE 文件上传的时候,如果读取了文件,那么将会将该文件锁住,这时候有个别软件(例如er图软件,但是大多数软件还是能操作该文件的,猜测是软件对文件进行检测)需要操作这个文件,发现文件被锁,尝试了以下方法都是不行:

1. input[type="file"] 方式上传,但是需要读取文件,er图软件无法获取文件操作权,即使通过 js 将input.value 置空

2. drag 文件拖拽,如果不读取文件,是可以操作,但是如果通过 e.dataTransfer.files[0] 读入文件,er图软件无法获取文件操作权

3. 通过form 方式上传,注意此时是没有 input[name=""] 属性的,这个时候通过js 将 input.value 置空之后 er图软件可以获得文件操作权。但是如果没有 input[name] 属性,服务端无法直接读取到该文件。因为 name 属性的作用相当于一个key索引,对提交到服务器后的表单数据进行标识,相当于已经通过 formdata.name="" 进行过封装之后再传递给服务端。所以如果input没有定义name属性,而且在封装 FormData直接通过 new FormData(form) 的方式封装,没有通过 formData.append('file', file) 将文件添加到formData里面,直接post到服务端是无法获取到该文件的。但是如果添加 input[name] 属性,则相当于读取了该文件,导致er图软件无法获取该文件操作权

4. 在山穷水尽处,幸得一大神指点,因为猜测是由于同源情况下(因为关闭tab页会释放)无法释放该文件,可以使用 iframe 嵌入 html 进行upload 操作,上传成功之后将 input.value 置空并且刷新该 iframe ,看看会不会释放该文件。经过一通 Ctrl+C 跟 Ctrl+V 之后,发现问题完美解决。证明了之前猜想是正确的。

贴下测试代码:

 1 <input type="file" name="file" id="file" onchange="fileChange(event)">
 2 
 3 <script type="text/javascript">
 4     function fileChange (event) {
 5         let file = event.target.files[0]
 6         let formData = new FormData()
 7         formData.append('file', file)
 8         let xhr = new XMLHttpRequest()
 9         xhr.open('POST', url)
10         xhr.onload = function () {
11             event.target.value = ''
12             file = null
13         }
14         xhr.send(formData)
15     }
16 </script>
View Code
1 <button onclick="reload(event)">reload</button>
2 <iframe src="./iframe.html" id="iframe"></iframe>
3 <script type="text/javascript">
4     function reload() {
5             document.getElementById('iframe').contentWindow.location.reload()
6     }
7 </script>

猜你喜欢

转载自www.cnblogs.com/l-c-blog/p/11253401.html