无法从 rails API return 二进制数据
Unable to return binary data from rails API
我使用 rails 中的 binary
数据类型将 base64url_encoded 字符串存储到 postgres 数据库中。这是迁移
def change
add_column :gmail_attachments, :base64_data, :binary
end
我正在存储的数据是来自 gmail API 的 base64 url 编码字符串。当我试图在 postgres 中将数据存储为 string
数据类型时,我得到了
ArgumentError (string contains null byte)
所以,我使用了二进制数据类型,它成功地存储到数据库中。现在,当我尝试
render status: 200, json: gmail_attachment_record
我收到以下错误
Encoding::UndefinedConversionError ("\xFF" from ASCII-8BIT to UTF-8):
如何消除此错误和 return 存储的数据?我是否将其存储在错误的数据类型中? rails ActiveRecord 数据类型中实现此目的的最佳选择是什么?
当您保存带有 :binary
列的模型时,Rails 将为您完成所有工作,确保正确设置编码以确保正确保存数据。
我认为您遇到了编码错误,因为 to_json
方法(通过 render
隐式调用)正试图通过 JSON.encode
将您的二进制字符串转换为 UTF-8。这就是您收到 UndefinedConversionError 的原因。 (ASCII-8BIT 是 ruby 中的一种特殊编码,本质上表示 BINARY。)
要进入工作状态,我认为您需要:
- 将您的数据保存到二进制列中,就像您在上面所做的那样 - 考虑将其命名为
data
。 (更好的是,使用 ActiveStorage 并将其保存到其他地方的文件中。)我建议您首先将数据从 base64 转换为原始二进制表示形式:
# Not sure what the api exactly looks like, but you get the idea
require('base64')
base64_data = Gmail.get_attachment(...)
gmail_attachment.data = Base64.decode64(base64_data) # now our data field is just the raw bytes.
gmail_attachment.save
- 然后您需要将其序列化回 base64,以便通过
to_json
传输。你可以通过这样的 as_json
方法来做到这一点:
# models/gmail_attachment.rb
require('base64')
class GmailAttachment < ApplicationRecord
def base64_data
Base64.encode64(self.data)
end
end
# controllers/your_controller.rb
render json: gmail_attachment_record.as_json(except: [:data], methods: [:base64_data])
很确定这会让您朝着正确的方向前进!
我使用 rails 中的 binary
数据类型将 base64url_encoded 字符串存储到 postgres 数据库中。这是迁移
def change
add_column :gmail_attachments, :base64_data, :binary
end
我正在存储的数据是来自 gmail API 的 base64 url 编码字符串。当我试图在 postgres 中将数据存储为 string
数据类型时,我得到了
ArgumentError (string contains null byte)
所以,我使用了二进制数据类型,它成功地存储到数据库中。现在,当我尝试
render status: 200, json: gmail_attachment_record
我收到以下错误
Encoding::UndefinedConversionError ("\xFF" from ASCII-8BIT to UTF-8):
如何消除此错误和 return 存储的数据?我是否将其存储在错误的数据类型中? rails ActiveRecord 数据类型中实现此目的的最佳选择是什么?
当您保存带有 :binary
列的模型时,Rails 将为您完成所有工作,确保正确设置编码以确保正确保存数据。
我认为您遇到了编码错误,因为 to_json
方法(通过 render
隐式调用)正试图通过 JSON.encode
将您的二进制字符串转换为 UTF-8。这就是您收到 UndefinedConversionError 的原因。 (ASCII-8BIT 是 ruby 中的一种特殊编码,本质上表示 BINARY。)
要进入工作状态,我认为您需要:
- 将您的数据保存到二进制列中,就像您在上面所做的那样 - 考虑将其命名为
data
。 (更好的是,使用 ActiveStorage 并将其保存到其他地方的文件中。)我建议您首先将数据从 base64 转换为原始二进制表示形式:
# Not sure what the api exactly looks like, but you get the idea
require('base64')
base64_data = Gmail.get_attachment(...)
gmail_attachment.data = Base64.decode64(base64_data) # now our data field is just the raw bytes.
gmail_attachment.save
- 然后您需要将其序列化回 base64,以便通过
to_json
传输。你可以通过这样的as_json
方法来做到这一点:
# models/gmail_attachment.rb
require('base64')
class GmailAttachment < ApplicationRecord
def base64_data
Base64.encode64(self.data)
end
end
# controllers/your_controller.rb
render json: gmail_attachment_record.as_json(except: [:data], methods: [:base64_data])
很确定这会让您朝着正确的方向前进!