【问题标题】:How can i change the XmlHttpRequest or FileAPI used in html5uploader to support IE如何更改 html5uploader 中使用的 XmlHttpRequest 或 FileAPI 以支持 IE
【发布时间】:2016-11-16 16:20:14
【问题描述】:

我将html5uploder 完美集成到我开发的网站中,但它并非设计用于与 IE 一起使用。但是客户现在希望至少支持 IE 10。即使 IE 支持 FileAPI,拖放文件上传器也不能与任何 IE 浏览器一起使用。

【问题讨论】:

    标签: javascript html internet-explorer cross-browser


    【解决方案1】:

    IE没有大问题,这段代码很容易适应微软浏览器。

    首先确保在 html 文件上强制浏览器进入“IE10”(或更高)模式(无怪癖,无兼容模式)。如果没有,所有的 javascript 都会失败,因为大部分代码不符合 IE9:

    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    

    当然,在其他浏览器中是没有考虑到的,所以没问题。

    现在,让我们修改一下 html5uploader.js 文件:

    • 第一个 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);
    

    完成!

    【讨论】:

      【解决方案2】:

      你的方法对我有用。我从 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
      

      【讨论】:

        猜你喜欢
        • 2023-03-31
        • 2019-07-24
        • 1970-01-01
        • 2020-09-22
        • 1970-01-01
        • 2023-03-19
        • 2015-12-19
        • 1970-01-01
        • 2012-07-02
        相关资源
        最近更新 更多