首页 > 解决方案 > rails ActiveStorage的blob表中的校验和是如何计算的

问题描述

有谁知道在 rails 5.2+ 上使用 ActiveStorage 时如何计算 active_storage_blobs 中的校验和字段?

对于奖励积分,有谁知道我怎样才能使用与 md5 CLI 命令中的校验和匹配的 md5 校验和?

标签: ruby-on-railsrails-activestorage

解决方案


让我们分解一下

我知道我参加聚会有点晚了,但这对于那些在寻找答案时遇到这个问题的人来说更是如此。所以在这里..

背景:

Rails 在 5.2 版本中引入了大量新特性,其中之一就是ActiveStorage。官方最终版本于 2018 年 4 月 9 日发布。

免责声明:

因此,为了清楚起见,以下信息与开箱即用的香草主动存储有关。这也没有考虑到一些围绕某个场景的疯狂代码fu。

话虽如此,校验和的计算方式会根据您的 Active Storage 设置而有所不同。使用 vanilla 开箱即用的 Rails Active Storage,有 2 种“类型”(因为没有更好的术语)配置。

  1. 代理上传
  2. 直接上传

代理上传

文件上传流程: [Client] → [RoR App] → [Storage Service]

通讯。流程:可能会有所不同,但在大多数情况下,它应该类似于文件上传流程。

SparkBao 的回答上面指出的是“代理上传”。这意味着您将文件上传到您的 RoR 应用程序并在将文件发送到您配置的存储服务(AWS、Azure、Google、BackBlaze 等)之前执行某种处理。即使您将存储服务设置为“localdisk”,该逻辑在技术上仍然适用,即使您的 RoR 应用程序是存储端点。

代理上传”方法对于在 Heroku 等服务上部署在云中的 RoR 应用程序并不理想。Heroku 有 30 秒的硬性限制来完成您的交易并将响应发送回您的客户(最终用户)。因此,如果您的文件相当大,您需要考虑文件上传所需的时间,然后考虑计算校验和所需的时间。如果您遇到无法在 30 秒内完成请求并做出响应的情况,您将需要使用“直接上传”方法。

代理上传答案:

正如 Spark.Bao所指出的,Ruby 类Digest::MD5用于方法compute_checksum_in_chunks(io) 。


直接上传

文件上传流程:【客户端】→【存储服务】

通讯。流程: [Client] → [RoR App] → [Client] → [Storage Service] → [Client] → [RoR App] → [Client]

我们维护和开发 Rails 的好朋友已经为我们完成了所有繁重的工作。我不会详细介绍如何设置直接上传,但这里有一个关于如何设置的链接 » Rails EdgeGuide - Direct Uploads

代理上传答案:

综上所述,使用开箱即用的“直接上传”设置,文件校验和是通过利用SparkMD5 (JavaScript) 计算的。

下面是来自Rails Active Storage 源代码的片段 - (activestorage.js)

  var fileSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice;
  var FileChecksum = function() {
    createClass(FileChecksum, null, [ {
      key: "create",
      value: function create(file, callback) {
        var instance = new FileChecksum(file);
        instance.create(callback);
      }
    } ]);
    function FileChecksum(file) {
      classCallCheck(this, FileChecksum);
      this.file = file;
      this.chunkSize = 2097152;
      this.chunkCount = Math.ceil(this.file.size / this.chunkSize);
      this.chunkIndex = 0;
    }
    createClass(FileChecksum, [ {
      key: "create",
      value: function create(callback) {
        var _this = this;
        this.callback = callback;
        this.md5Buffer = new sparkMd5.ArrayBuffer();
        this.fileReader = new FileReader();
        this.fileReader.addEventListener("load", function(event) {
          return _this.fileReaderDidLoad(event);
        });
        this.fileReader.addEventListener("error", function(event) {
          return _this.fileReaderDidError(event);
        });
        this.readNextChunk();
      }
    },

结论

如果有什么我错过了,我会提前道歉。我试图尽可能彻底。

因此,总结以下内容应该足以作为可接受的答案:

  • 代理上传配置: ruby 类Digest::MD5

  • 直接上传配置: JavaScript 哈希库SparkMD5


推荐阅读