我目前正在组合一个基于 Rails 的 Web 应用程序,它只能通过 json 和 xml 提供和接收数据。但是,某些要求包含上传二进制数据(图像)的能力。
现在,据我了解,JSON 并不完全是为了这个……但是您通常如何解决通过应用程序的这两个入口点接收二进制文件/数据的问题?
我目前正在组合一个基于 Rails 的 Web 应用程序,它只能通过 json 和 xml 提供和接收数据。但是,某些要求包含上传二进制数据(图像)的能力。
现在,据我了解,JSON 并不完全是为了这个……但是您通常如何解决通过应用程序的这两个入口点接收二进制文件/数据的问题?
我建议将二进制数据编码为 base64 之类的东西。这样可以安全地以 XML 或 JSON 格式使用。
如果您使用的是 Rails 和 json 和 xml,那么您使用的是 HTTP。“POST”是 HTTP 的一部分,是转换二进制数据的最佳方式。Base64 是一种非常低效的方法。
如果您的服务器正在发送数据,我建议您在服务器上以 XML 或 JSON 格式放置文件路径。这样,您的服务器不必对数据进行 base64 编码,而您的客户端已经支持 HTTP GET,可以在不解码的情况下提取数据。(获取/路径/到/文件)
对于发送文件,让您的服务器和/或客户端生成唯一的文件名并使用两步过程;客户端将使用 fileToBeUploaded: "name of file.ext" 发送 xml 或 json 消息,发送消息后将使用上述文件名 POST 数据。同样,客户端和服务器不必对数据进行编码和解码。这可以通过使用多部分请求的一个请求来完成。
Base64 很简单,但会根据数据大小和请求频率迅速消耗 CPU 和/或内存。在服务器端,它也不是缓存操作,而 Web 服务器从磁盘读取文件的操作是缓存的。
如果您的图像不是太大,将它们放入具有 RoR :binary 类型的数据库很有意义。如果您有数据库副本,则图像可以免费复制到其他站点,无需担心孤立或寡居的图像,并且原子事务问题变得更加简单。
另一方面,Nessence 是正确的,Base64 与任何编码层一样,确实为事务增加了网络、内存和 CPU 负载。如果网络带宽是您的首要问题,请确保您的 Web 服务接受并提供 deflate/gzip 压缩连接。这将降低网络层 Base64 数据的成本,尽管代价是更多的内存和 CPU 负载。
这些是应该与您的团队和/或客户讨论的架构问题。
最后,让我向您介绍一下 RoR 的 XML REST 支持。当您使用默认脚手架中的以下代码呈现到 XML 时,Rails:binary
数据库类型将成为XML 对象:<object type="binary" encoding="base64">...</object>
def show
@myobject = MyObject.find(:id)
respond_to do |format|
format.xml { render => @myobject }
end
end
这对于 GET 操作非常有用,而且 PUT 和 POST 操作也很容易编写。问题是 Rails PUT 和 POST 操作不接受相同的标签。这是因为from_xml
代码不解释type="binary"
标签,而是寻找type="binaryBase64"
. Rails 灯塔站点上有一个补丁程序错误来纠正这个问题。