我将html5uploder完美地集成到我开发的网站中,但它并非设计为与 IE 一起使用。但是客户现在希望至少支持 IE 10。即使 IE 支持 FileAPI,拖放文件上传器也不适用于任何 IE 浏览器。
2 回答
IE没有大问题,这段代码很容易适应微软浏览器。
首先确保在 html 文件中强制浏览器进入“IE10”(或更高)模式(无怪癖,无兼容模式)。如果没有,所有的 javascript 都会失败,因为大部分代码不符合 IE9:
<meta http-equiv="X-UA-Compatible" content="IE=edge">
当然,在其他浏览器中是没有考虑到的,所以没问题。
现在,让我们稍微修改一下 html5uploader.js 文件:
First
readAsBinaryString
在 IE10 中不被接受。您可以将其替换为readAsDataURL
,但这会改变您提交文件的方式,以及您必须接收它的方式(在 php 中)if (navigator.appName === "Microsoft Internet Explorer") { reader.readAsDataURL(file); } else { reader.readAsBinaryString(file); }
其次,
sendAsBinary
在 IE 上不起作用,并且不相关,因为我们现在正在使用readAsDataURL
. 所以我们必须将我们的文件作为 base64 字符串提交,之后我们将转换为二进制文件(在 php 中)。只需发送它xhr.send
最后,
btoa
是 Mozilla 实现的一个功能,在 Chrome 中也可以使用。我认为不能在 IE10 中使用。但没问题,因为readAsDataURL
会将您的文件读取为 base64 字符串!所以只需发送它xhr.send((bin));
所以它给出了:
if(xhr.sendAsBinary != null) {
xhr.sendAsBinary(body);
// Chrome and IE10 sends data but you must use the base64_decode on the PHP side
} else {
if (navigator.appName === "Microsoft Internet Explorer") {
xhr.open('POST', targetPHP+'?up=true&browser=IE&filename='+encodeURI(file.name), true);
} else {
xhr.open('POST', targetPHP+'?up=true&browser=chrome&filename='+encodeURI(file.name), true);
}
xhr.setRequestHeader('UP-FILENAME', file.name);
xhr.setRequestHeader('UP-SIZE', file.size);
xhr.setRequestHeader('UP-TYPE', file.type);
if (navigator.appName === "Microsoft Internet Explorer") {
xhr.send((bin)); // in IE, it s already base64, no need conversion
} else {
xhr.send(window.btoa(bin)); // in Chrome, it s binary, so conversion to base64 is needed
}
}
请注意,在服务器端,我无法获取标头,getallheaders()
因为此功能在 IIS 和 PHP 5.2 上不起作用,所以我直接通过 URL 传输文件名!
所以现在我们在 PHP 中有 3 个案例:
- Firefox 将作为二进制发送,易于使用
$_FILES['upload']['tmp_name']
然后移动它。 - 在 IE 中,我们得到
$_GET['browser']=='IE'
.
我们得到文件的内容是这样的:
$content = file_get_contents('php://input'); //the string we get contains 2 parts
$content = str_replace(' ','+',$content); // we need to replace spaces by plusses
$content = split(",",$content); // we do not need the first part of the string (the one with the file type).
$content = base64_decode($content[1]); // we decode the base64 to binary
- 在 Chrome 中,我们得到
$_GET['browser']=='chrome'
.
我们得到文件的内容是这样的: $content = base64_decode(file_get_contents('php://input'));
//easy 因为它已经是一个base64编码的二进制文件,所以只需要解码它!
对于 IE 和 chrome,我们使用以下命令创建文件:
$filename = urldecode($_GET['filename']); // because I cannot get headers...
file_put_contents($upload_folder.'\\'.$filename, $content);
完毕 !
你的方法对我有用。我从 JS 和服务器中删除了 IE 特定条件。它适用于 IE10、IE11、Chrome。
Javascript
private onFileChange(e) {
var file = _.first(e.target.files);
if (!file) { return; }
var xhr = new XMLHttpRequest();
xhr.open("POST", '/upload', true);
xhr.setRequestHeader("Session-Id", 'secret');
var reader = new FileReader();
reader.onload = function(){
xhr.send(this.result);
};
reader.readAsDataURL(file);
}
在 Rails 服务器上
class UploadsController < ApplicationController
def create
file_id = DateTime.current.strftime('%Y_%m_%d_%H_%M_%S_%L') + '_' +
SecureRandom.hex
base64_content = request.body.read.to_s.split(',').last
file_content = Base64.decode64(base64_content)
File.open("tmp/#{file_id}", 'wb'){ |f| f.write(file_content) }
render json: { id: file_id }
end
end