首页 \ 问答 \ 无法使用JavaScript FileReader API上传二进制文件(Trouble uploading binary files using JavaScript FileReader API)

无法使用JavaScript FileReader API上传二进制文件(Trouble uploading binary files using JavaScript FileReader API)

javascript新手,无法解决这个问题,帮助!

我正在尝试使用Javascript FileReader API来读取要上载到服务器的文件。 到目前为止,它适用于文本文件。

当我尝试上传二进制文件(如image / .doc)时,文件似乎已损坏,并且无法打开。

在客户端使用dojo,在服务器端使用java,使用dwr处理远程方法调用。 代码:

使用html文件输入,用户可以选择一次上传多个文件:

<input type="file" id="fileInput" multiple>

以及读取文件内容的j​​avascript代码:

        uploadFiles: function(eve) {
        var fileContent = null;

        for(var i = 0; i < this.filesToBeUploaded.length; i++){
            var reader = new FileReader();
            reader.onload = (function(fileToBeUploaded) {
                return function(e) {
                    fileContent = e.target.result;
                    // fileContent object contains the content of the read file
                };
            })(this.filesToBeUploaded[i]);

            reader.readAsBinaryString(this.filesToBeUploaded[i]);
        }            
    }

fileContent对象将作为参数发送到java方法,该方法将写入该文件。

    public boolean uploadFile(String fileName, String fileContent) {
    try {
        File file = new File("/home/user/files/" + fileName);
        FileOutputStream outputStream = new FileOutputStream(file);
        outputStream.write(fileContent.getBytes());
        outputStream.close();
    } catch (FileNotFoundException ex) {
        logger.error("Error uploading files: ", ex);
        return false;
    } catch (IOException ioe) {
        logger.error("Error uploading files: ", ioe);
        return false;
    }
    return true;
}

我已经阅读了一些建议使用xhr和servlet来实现这一目标的答案。

有没有办法使用FileReader,以便它可以读取任何类型的文件(文本,图像,Excel等)?

我尝试过使用reader.readAsBinaryString()reader.readAsDataUrl() (在写入文件之前解码base64 fileContent),但它们似乎没有用。

PS:1。还尝试过reader.readAsArrayBuffer() ,结果ArrayBuffer对象显示了一些byteLength ,但没有内容,当这个传递给服务器时,我看到的只是{}

  1. 这段代码仅适用于较新版本的浏览器。

New to javascript, having trouble figuring this out, help!

I am trying to use the Javascript FileReader API to read files to upload to a server. So far, it works great for text files.

When I try to upload binary files, such as image/.doc, the files seem to be corrupted, and do not open.

Using dojo on the client side, and java on the server side, with dwr to handle remote method calls. Code :

Using a html file input, so a user can select multiple files to upload at once :

<input type="file" id="fileInput" multiple>

And the javascript code which reads the file content:

        uploadFiles: function(eve) {
        var fileContent = null;

        for(var i = 0; i < this.filesToBeUploaded.length; i++){
            var reader = new FileReader();
            reader.onload = (function(fileToBeUploaded) {
                return function(e) {
                    fileContent = e.target.result;
                    // fileContent object contains the content of the read file
                };
            })(this.filesToBeUploaded[i]);

            reader.readAsBinaryString(this.filesToBeUploaded[i]);
        }            
    }

The fileContent object will be sent as a parameter to a java method, which will write the file.

    public boolean uploadFile(String fileName, String fileContent) {
    try {
        File file = new File("/home/user/files/" + fileName);
        FileOutputStream outputStream = new FileOutputStream(file);
        outputStream.write(fileContent.getBytes());
        outputStream.close();
    } catch (FileNotFoundException ex) {
        logger.error("Error uploading files: ", ex);
        return false;
    } catch (IOException ioe) {
        logger.error("Error uploading files: ", ioe);
        return false;
    }
    return true;
}

I have read some answers suggesting the use of xhr and servlets to achieve this.

Is there a way to use FileReader, so that it can read files of any type (text, image, excel etc.) ?

I have tried using reader.readAsBinaryString() and reader.readAsDataUrl() (Decoded the base64 fileContent before writing to a file), but they did not seem to work.

PS : 1. Also tried reader.readAsArrayBuffer(), the resultant ArrayBuffer object shows some byteLength, but no content, and when this is passed to the server, all I see is {}.

  1. This bit of code is intended to work on only newer versions of browsers..

原文:https://stackoverflow.com/questions/27855052
更新时间:2021-07-31 11:07

最满意答案

谢谢NM! 因此,看起来不能直接使用ArrayBuffer对象,并且必须创建DataView才能使用它们。 以下是有效的 -

    uploadFiles: function(eve) {
    var fileContent = null;

    for(var i = 0; i < this.filesToBeUploaded.length; i++){
        var reader = new FileReader();
        reader.onload = (function(fileToBeUploaded) {
            return function(e) {
                fileContent = e.target.result;
                var int8View = new Int8Array(fileContent);
                // now int8View object has the content of the read file!
            };
        })(this.filesToBeUploaded[i]);

        reader.readAsArrayBuffer(this.filesToBeUploaded[i]);
    }            
}

将NM的评论引用到相关页面链接的问题。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays


Thanks N.M! So, it looks like ArrayBuffer objects cannot be used directly, and a DataView must be created in order to use them. Below is what worked -

    uploadFiles: function(eve) {
    var fileContent = null;

    for(var i = 0; i < this.filesToBeUploaded.length; i++){
        var reader = new FileReader();
        reader.onload = (function(fileToBeUploaded) {
            return function(e) {
                fileContent = e.target.result;
                var int8View = new Int8Array(fileContent);
                // now int8View object has the content of the read file!
            };
        })(this.filesToBeUploaded[i]);

        reader.readAsArrayBuffer(this.filesToBeUploaded[i]);
    }            
}

Refer N.M 's comments to the question for links to the relevant pages.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays

相关问答

更多
  • 您需要处理FileReader的load事件。 在处理程序中,访问reader.result或this.result : reader.onload = function() { var contents = this.result; }; 读取文件是一种异步操作。 因此,您需要为每个文件创建单独的FileReader 。 如果要重用相同的FileReader ,则不能使用for循环。 相反,您必须等待读取下一个文件,直到处理完当前文件。 You need to handle the load e ...
  • 答案写在你链接的页面上。 如果您使用的是Chrome,则此代码必须在服务器上运行(本地主机或站点上)。 它不会与本地文件一起使用。 我的代码在运行时记录了所有3条消息。 The answer is written in the very page that you linked. If you are on chrome, this code has to be running on a server (localhost or on a site). It won't work with a local ...
  • 这不是因为FileReader而是因为你将audio元素的src属性设为1.33 * mp3filesize字符串。 因此, src属性不是一个指向mp3资源的漂亮短URL,而是base64编码的整个mp3文件。 这是一个奇迹,你的浏览器没有崩溃。 您根本不应该使用FileReader读取该文件,而是从该文件创建一个blob URL并将其用作src。 var url = window.URL || window.webkitURL; //Src will be like "blob:http%3A//st ...
  • 在IE中,您应该使用ActiveXObject,因为IE不是浏览器 In IE you should use ActiveXObject because IE is not a browser
  • 您的upload()函数并不总是返回Promise。 它在else条件下,但if条件没有。 你有一个return语句,但它在回调中 ,所以upload的调用者不会收到它。 尝试将其更改为: function upload() { if (start < end) { return new Promise(function (resolve, reject) { var chunk = uploading_file.slice(start, temp_end); var r ...
  • HTML5 fileReader工具允许您处理本地文件,但这些必须由用户选择,您无法查找用户磁盘查找文件。 是否可以在非服务页面上加载带有JS / HTML5 FileReader的文件? 如何用Javascript打开本地磁盘文件? 如何在HTML中设置文件输入的值? Javascript不使用输入读取文件 这些链接可以帮助您找到答案。 The HTML5 fileReader facility does allow you to process local files, but these MUST b ...
  • FileReader需要一个Blob 。 哪个是表示内存中二进制文件的对象。 Blob来自哪里并不重要,但是您需要让浏览器分配内存,以便FileReader可以访问它。 FileReader本身不会下载任何东西。 因此,如果您正在讨论存储在服务器上的文件,那么浏览器必须将其从该处下载到计算机的内存中。 至于如何实现这一点,最常见的AJAX有很多种方法,只要数据从服务器下载并可访问,至少可以从中构建Blob,然后FileReader会很开心。 如果您正在讨论存储在用户磁盘上的文件,那么浏览器需要被授予访问权限 ...
  • 您有一个logic error : reader.onload = (function (e) { //onload code //inside function e is event from outside })(e);//e is event from upper code 而i将等于files.length因为onload处理程序是异步的。 因此,您必须将onload处理程序更改为: reader.onload = function (index) { var img = ...
  • 谢谢NM! 因此,看起来不能直接使用ArrayBuffer对象,并且必须创建DataView才能使用它们。 以下是有效的 - uploadFiles: function(eve) { var fileContent = null; for(var i = 0; i < this.filesToBeUploaded.length; i++){ var reader = new FileReader(); reader.onload = (functio ...
  • 解码数据URI 您可以对readAsDataURL提供的版本进行base64解码。 这是一个天真的实现。 require 'base64' decoded_result = Base64.decode64(data.gsub('data:image/jpeg;base64,', '')) 有一个库可以在Ruby中正确处理数据URI 使用普通表单上传文件 代码链接 有一个用于在Ember上传图像的库,请阅读其代码。 你对这些领域特别感兴趣。 用于处理事件的输入视图 要上传什么 如何创建表单 如何上传 摘抄 ...

相关文章

更多

最新问答

更多
  • 在可观察字段Knocout中显示$符号(Display $ sign in observable fields Knocout)
  • 全局和设备功能之间的差异(Difference between global and device functions)
  • ARM,MCU,DSP,FPGA,SOC各是什么?区别是什么
  • Facebook JavaScript SDK登录(Facebook JavaScript SDK Login)
  • 会计实操有没有用,北京哪家会计培训最好?
  • 字段列表错误中的MySQL未知列(MySQL Unknown column in fieldlist error)
  • 在DOM深层获取评论节点(Get comment nodes in DOM deep level)
  • 2015年的会计上岗证培训那里好,在西安
  • 将long lat转换为google maps long lat(converting long lat to google maps long lat)
  • XSD xs:列表混乱(XSD xs:list confusion)
  • 在Wordpress中,有没有办法让导航下拉菜单显示一个类别中的帖子?(In Wordpress, is there a way to make the navigation drop down menu show posts in a category?)
  • 当我想清空名为python的列表时,del a [:]和a = []之间有什么区别?(what is the difference between del a[:] and a = [] when I want to empty a list called a in python? [duplicate])
  • 我的第一个项目入门与设备之间的连接(Getting started with my first project with connectivity between devices)
  • azure site-to-site-vpn不允许流量通过(azure site-to-site-vpn does not let traffic through)
  • GoogleMaps - 调用onPause()(GoogleMaps - calling onPause())
  • 教师爱岗敬业演讲稿
  • 我正在编写c#代码,其中我想从Active Directory中搜索特定用户的详细信息(I am writing c# code wherein I want search for the details of a specific user from Active Directory)
  • sonar lint插件无法读取lint-results.xml(sonar lint plugin fails reading lint-results.xml)
  • Swift UITableView - 如何将新项目置于列表底部而不是列表的底部?(Swift UITableView - How to put new items on top not on the bottom of the list?)
  • 无法将“System.DBNull”类型的对象强制转换为MySQL Image的“System.Byte []”类型[复制](Unable to cast object of type 'System.DBNull' to type 'System.Byte[]' for MySQL Image [duplicate])
  • 在这种情况下我为Android登录RESTful api调整了什么?(What i adjust for android login into RESTful api in this conditions?)
  • 使用DBMS的C#VSTO(C# VSTO with DBMS)
  • 在NSTableView中更改自定义按钮单元格的图像(Change image of custom button cell inside NSTableView)
  • 从数据库中选择数据,选择任何行(select data from database with where selected any rows)
  • 与Grails持续集成(Continuous Integration with Grails [closed])
  • Laravel 4中的嵌套控制器(Nested Controllers in Laravel 4)
  • Qt - 插槽完成后不要销毁线程(Qt - don't destroy thread after slot is finished)
  • mysql 主从配置 需要什么网络环境
  • Spring 4可选> @RequestParam(Spring 4 Optional> @RequestParam)
  • 移动类型char,类似的赋值行为不同(Shifting a type char, similar assignments behave differently)