【问题标题】:How to make a SHA1 from a file in Angular using a filereader?如何使用文件阅读器从 Angular 中的文件制作 SHA1?
【发布时间】:2019-10-11 02:02:00
【问题描述】:

我的 html 页面上有一个输入元素,我可以使用它选择 1/多个文件。
选择文件后,我想使用 FileReader 读取每个文件的内容以从中生成 SHA1。
获得 SHA1 值后,我想将其保存在某个地方。

问题是我仅在 FileReader 的 .onload 完成后才收到 SHA1 值,并且在我尝试保护它的值之后发生。

我试图使函数异步并使用等待等待文件被读取,但这不起作用。 我曾尝试添加一个 Promise,但这也没有用。
我真的不知道该怎么做才能达到预期的结果。请帮忙。

这是我在选择文件时调用的角度函数:

hashFiles(files: Array<any>){
    console.log('start hashing');
    for (const file of files) {
      const myHash = hashFile(file);
      console.log('hash: ', myHash);
      /*I would like to save myHash here*/
    }
    console.log('done hashing');
}

这是我从 Angular 调用的 javascript 函数,它将使用 FileReader 读取文件,然后从其内容中生成 sha1 哈希

function hashFile(fileToHandle) {
  console.log('1');

  var reader = new FileReader();

  console.log('2');

  reader.onload = (function() {

    return function(e) {
      console.log('4');

      const hash = CryptoJS.SHA1(arrayBufferToWordArray(e.target.result)).toString();
      console.log('hash result in fileReader: ', hash);
      return hash;
    };
  }) (fileToHandle);
  reader.onerror = function(e) {
    console.error(e);
  };

  console.log('3');

  reader.readAsArrayBuffer(fileToHandle);

  console.log('5');
}

function arrayBufferToWordArray(ab) {
  var i8a = new Uint8Array(ab);
  var a = [];
  for (var i = 0; i < i8a.length; i += 4) {
    a.push(i8a[i] << 24 | i8a[i + 1] << 16 | i8a[i + 2] << 8 | i8a[i + 3]);
  }
  return CryptoJS.lib.WordArray.create(a, i8a.length);
}

运行此代码时,我的控制台中有以下内容:

start hashing
1
2
3
5
hash: undefined
done hashing
4
hash result in fileReader: 327c468b64b4ca54377546f8a214d703ccbad64b

我需要它是:

start hashing
1
2
3
hash result in fileReader: 327c468b64b4ca54377546f8a214d703ccbad64b
4
5
hash: 327c468b64b4ca54377546f8a214d703ccbad64b
done hashing

这是我的代码示例:
https://stackblitz.com/edit/sha1-from-file

【问题讨论】:

  • 可以分享代码吗?你用 async/await 和 promises 尝试过什么?
  • 嗨,我已经用我的代码添加了一个 stackblitz 项目。

标签: javascript angular filereader sha1 cryptojs


【解决方案1】:

您需要使用回调或向FileReader 的本机回调添加一个承诺包装器(observable 也可以)。以下是您只需添加回调即可做到这一点的方法。

Stackblitz

app.component.ts

hashFiles(event) {
  console.log('start hashing');

  const numberOfFiles = event.target.files.length;
  var fileCounter = 0;
  for (const file of event.target.files) {
    hashFile(file, (hashedFile, hash) => {
    console.log('hash: ', hash);
    fileCounter++;
    if(fileCounter === numberOfFiles)
      console.log('Done Hashing!');
    });
  }
}

script.js

export function hashFile(fileToHandle, callback) {
  var CryptoJS = require("crypto-js");

  console.log('1');

  var reader = new FileReader();

  console.log('2');

  reader.onloadend = (function() {
    return function(e) {
      console.log('4');
      const hash = CryptoJS.SHA1(arrayBufferToWordArray(e.target.result)).toString();
      console.log('hash result in fileReader: ', hash);
      callback(fileToHandle, hash);
    };
  }) (fileToHandle);
  reader.onerror = function(e) {
    console.error(e);
  };

  console.log('3');

  reader.readAsArrayBuffer(fileToHandle);
}

【讨论】:

  • 为什么选择覆盖reader.onloadend而不是通过addEventListener方法注册handler?
猜你喜欢
  • 2013-09-17
  • 1970-01-01
  • 2021-03-30
  • 1970-01-01
  • 2016-12-18
  • 1970-01-01
  • 1970-01-01
  • 2020-02-20
  • 2016-07-28
相关资源
最近更新 更多