ruby-on-rails - rails ActiveStorage的blob表中的校验和是如何计算的
问题描述
有谁知道在 rails 5.2+ 上使用 ActiveStorage 时如何计算 active_storage_blobs 中的校验和字段?
对于奖励积分,有谁知道我怎样才能使用与 md5 CLI 命令中的校验和匹配的 md5 校验和?
解决方案
让我们分解一下
我知道我参加聚会有点晚了,但这对于那些在寻找答案时遇到这个问题的人来说更是如此。所以在这里..
背景:
Rails 在 5.2 版本中引入了大量新特性,其中之一就是ActiveStorage。官方最终版本于 2018 年 4 月 9 日发布。
免责声明:
因此,为了清楚起见,以下信息与开箱即用的香草主动存储有关。这也没有考虑到一些围绕某个场景的疯狂代码fu。
话虽如此,校验和的计算方式会根据您的 Active Storage 设置而有所不同。使用 vanilla 开箱即用的 Rails Active Storage,有 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。
推荐阅读
- junit - 具有持久性、非静态字段的 JUnit 测试类
- javascript - 使用 chrome.storage 'set' 推送的数组不会出现在 'get' 中
- javascript - Javascript 基本算法 - QUEUE
- angular - ngx-datatable (select) 操作不会重新呈现所选行数
- mysql - 导入大 sql 文件时如何计算 mysql 的最大性能?
- c# - 我已经尝试重新安装 ms office 并安装了 office 工具运行时。将数据导出到 Excel 文件时仍然出现此错误
- selenium - 在 Selenium 中添加鼠标操作
- android - 无法获取设备的 UUID
- sql - 我将如何创建一个查询,为我提供相同购买的客户的姓名
- javascript - dropzonejs 预览容器