【问题标题】:FileReader onload only works the second time around in browsersFileReader onload 仅在浏览器中第二次起作用
【发布时间】:2017-01-02 17:24:51
【问题描述】:

我正在使用 HTML5 进行浏览器内图像处理,并且在 Chrome 中使用 File API FileReader 类的 onload 事件处理程序时遇到了一个奇怪的问题,该文件仅在第二次在表单中被选中时才被正确处理。

知道如何让 Chrome 首次处理此事件吗? 在我的控制台网络中,当我单击编辑图像时,当我第二次单击编辑按钮时,不会出现任何内容,会出现带有图像 blob 的 profilePic。 IDK 发生了什么。

代码:

function uploadFile(){
    var file = $scope.profilePic;
    console.log(file);
    var blob = new Blob([file], {
        "type": "text/html"
    });

    var reader = new FileReader();

    reader.onload = function(e) {
        var text = e.target.result.split(',')[1];
        console.log(text);
        $scope.loadedUser.profilePic = text;
    }

    reader.readAsDataURL(blob);
}; 

html:

<div layout-gt-sm="row" style="margin-bottom: 20px;">                                                    
    <input type="file" name="profilePic" fileread="profilePic"> 
</div>

【问题讨论】:

  • 我很困惑,如果是图像,为什么要创建它的 html blob,实际上,为什么还要创建文件的 blob?文件是 Blob。
  • 我需要将图像转换为 blob 以发送后端。
  • 但是“文件就是 Blob”!你可以用 Blob 做的任何事情都可以用 File 来完成。你不需要转换它,而且不需要转换成它不是的东西。
  • 但是后端如何将文件转换为数据库的 blob?我在前端转换,因为后端发送到数据库已经转换
  • 不,你不明白。在您发布的代码中,您将文件从文件输入转换为 text/html Blob。文件对象是 Blob 的超集,并共享它的所有属性,+ 一个名称。所以 FileReader 可以直接读取 File。无需将其转换为 Blob。但既然我们在那里,最好将您的文件作为多部分请求直接发送到服务器(感谢 FormData API)并在服务器端进行 b64 转换。我不知道你在使用什么服务器端,但我确信有一种干净的方法来处理.multipart 文件并将任何内容转换为 b64。

标签: javascript html angularjs


【解决方案1】:

快速解决方法是使用$scope.$apply:

reader.onload = function(e) {
    var text = e.target.result.split(',')[1];
    console.log(text);
    $scope.loadedUser.profilePic = text;
    //USE $apply
    $scope.$apply();
}

reader.onload 事件是发生在 AngularJS 框架之外的浏览器事件。对 AngularJS 范围的任何更改都需要使用以 $scope.$apply() 开头的 AngularJS 摘要循环进行处理。


(来源:angularjs.org

-- AngularJS Developer Guide (v1.1.5) - Concepts - Runtime

【讨论】:

  • 感谢您的评论。但是当我尝试更新图像时,我继续出现同样的错误。从那以后只有2次。我陷入了这个问题
【解决方案2】:

&lt;object&gt; 标签和 blob 文件也有同样的问题。

我从服务器获取了文件的数据并制作了一个 blob 文件,并尝试使用&lt;object&gt; 标记以模式显示它。 在我添加了一个加载图标并因此添加了一个加载标志(或变量)之前,每件事都做得很好。我使用ng-if 来处理带有这个加载标志的&lt;object&gt; 标签。 这导致&lt;object&gt; 标签无法正确加载。从那时起,文件在我第一次打开模式时没有显示,但是当我第二次打开模式时显示正确,我第二次没有从服务器获取文件,因此没有加载(没有加载第二次,因为文件已经在访问中)。

为了克服这个问题,我尝试并改变了很多东西,但都没有成功。 $scope.$apply() 对我不起作用。然后我将标志ng-if更改为ng-show,这样&lt;object&gt;第一次正确加载,因此文件也显示出来了。

【讨论】:

    猜你喜欢
    • 2015-08-07
    • 1970-01-01
    • 2012-04-21
    • 1970-01-01
    • 2020-08-06
    • 1970-01-01
    • 1970-01-01
    • 2018-11-12
    • 2020-07-25
    相关资源
    最近更新 更多