在JSON对象中存储和发送原始文件数据

Storing and sending raw file data within a JSON object

本文关键字:原始 文件 数据 JSON 对象 存储      更新时间:2023-09-26

我正在寻找一种方法来传输任何文件类型的原始文件数据与任何可能的内容(我的意思是文件和文件内容都是用户生成的)两种方式使用xhr/ajax调用在主干前端对Django后端。


编辑:也许这个问题还不清楚…

如果您在IDE中打开一个文件(例如Sublime),您可以查看和编辑包含该文件的实际代码。我试图把原始内容成JSON,所以我可以发送到浏览器,它可以修改,然后发送回来。

我发布了这个问题,因为我的印象是,因为这些文件的内容可以有效地在任何编码语言,只是将内容字符串化并发送它似乎像一个脆弱的解决方案,很容易打破或利用。内容可以包含任何数量的', ", {}字符,这些字符似乎会破坏JSON格式,并且转义这些字符会在代码中留下工件,从而有效地破坏它们(不是吗?)。

如果这个假设是错误的,那也是一个可以接受的答案(只要你能指出我忽略了什么)。


我正在研究的项目是一个基于浏览器的IDE,它将从服务器接收完整的文件结构。用户可以添加/删除文件,编辑这些文件的内容,然后将更改保存回服务器。发送/接收都必须通过ajax/xhr调用来处理。

  • 在Backbone中,每个"文件"被实例化为一个模型并存储在一个集合中。文件的内容将作为模型的属性存储。
  • 理想情况下,当发生更改时,文件内容仍然可靠地抛出所有适当的事件。
  • 获取内容不应该从文件模型的其余部分中分离出来,单独调用。我想只使用一个保存/获取调用发送/接收文件,包括原始内容。

需要Underscore/jQuery的解决方案很好,如果有专门管理原始文件数据的可用工具,我可以引入其他库。

有趣的问题。实现这一点所需的代码将相当复杂,对不起,我没有提供示例,但你看起来像一个体面的程序员,应该能够实现下面提到的内容。

关于通过JSON发送原始数据,您所需要做的就是使用Python的JSON进行字符串化来转义特殊字符,从而使其对JSON安全且不会破坏代码。转储,JavaScript的JSON.stringyfy。[1]

如果您关心某种形式的基本防篡改,那么除了让客户端和服务器在JSON传输中来回传递每个会话令牌以确保JSON不会从恶意地址伪造之外,对数据进行轻编码将符合目的。

如果你想检查端到端的完整性的数据,然后生成一个md5校验和发送到JSON中,然后在到达时生成另一个md5并与JSON中的md5进行比较。

Base64编码:你的数据大小将增长33%,因为它编码四个字符来表示三个字节的数据。

Base85:将四个字节编码为五个字符,并将数据增长25%,但比Python中的Base64使用更多的处理开销。这在数据大小上提高了8%,但代价是处理开销。它也不是字符串安全的双&单引号、尖括号和&号不能在JSON中不转义地使用,因为它使用了所有95个可打印的ASCII字符。需要在JSON传输之前进行字符串化。[2]

yEnc的开销只有2-3%(取决于数据中相同字节的频率),但由于不切实际的缺陷而被排除在外(参见[3])。

ZeroMQ base - 85 ,又名 Z85 。它是Base85的字符串安全变体,数据开销为25%,优于Base64。将其插入JSON中不需要进行字符串化。我强烈推荐这种编码算法。[4] [5] [6]

如果您只发送小文件(比如几KB),那么二进制到文本转换的开销将是可以接受的。对于大小只有几mb的文件,让它们增长25-33%可能是不可接受的。在这种情况下,您可以在发送之前尝试压缩它们。[7]

你也可以使用multipart/form-data向服务器发送数据,但我看不出这是如何双向工作的。

总之,这是我的解决方案的算法:

  • 生成会话令牌并为关联用户存储登录(服务器),或者从会话cookie(客户端)中检索

  • 为数据生成MD5哈希值,用于传输过程中的完整性检查。

  • 用Z85对原始数据进行编码,增加一些基本的防篡改和json友好性。

  • 将上述内容放入JSON中,并在请求时发送POST。

接待

  • 从POST获取JSON

  • 从存储中为关联用户(服务器)检索会话令牌,或从会话cookie(客户端)检索。

  • 为接收到的数据生成MD5哈希值,并对接收到的JSON中的MD5进行测试,有条件地拒绝或接受

  • z85 -对接收到的JSON中的数据进行解码,得到原始数据,根据需要存储在文件或DB(服务器)中,或在GUI/IDE(客户端)中处理/显示。


引用

[1]如何在构建JSON字符串时转义特殊字符?

[2]二进制数据在JSON字符串。比Base64更好的

[3] https://en.wikipedia.org/wiki/YEnc

[4] http://rfc.zeromq.org/spec: 32

[5] Z85的C/c++实现https://github.com/artemkin/z85

[6] Z85 Python实现https://gist.github.com/minrk/6357188

[7] JavaScript压缩库http://stuk.github.io/jszip/

[8] JavaScript Gzip SO JavaScript实现Gzip

我担心一个简单的Base64转换将做到这一点。将其字符串化,转换为base64,然后将其传递给服务器并在那里解码。这样你就不会有原始文件传输,你仍然会保持你的代码简单。

我知道这个解决方案看起来有点太简单了,但是想想看:只要有合适的硬件,许多加密算法都可以被破解。最安全的方法之一是通过数字证书,然后用私钥加密数据,然后将其发送到服务器。但是,要达到这种级别的安全,您的应用程序的每个用户都必须拥有数字证书,我认为这对您的用户来说是一个过高的要求。

所以问问你自己,如果实现一个真正安全的解决方案给你的用户增加了很多麻烦,为什么你需要一个安全的传输?基于此,我重申我之前所说的。一个简单的Base64转换就可以了。你也可以使用其他一些算法,比如SHA256之类的,让它更安全一点。

如果这里唯一关心的是代码文件的原始内容(模型存储的"数据")在存储在JSON中时会导致某种类型的问题,这很容易通过转义您的数据。

将原始代码文件内容字符串化可能会导致问题,因为任何类似JavaScript或JSON的内容都将被解析为实际的JSON对象。您的代码文件数据可以并且应该简单地存储为转义字符串。您在这里担心的是,所述字符串可能包含可能在JavaScript中存储在字符串中的字符,这可以通过转义整个字符串来缓解,从而转义代码文件中已经转义的任何内容。

本质上,重要的是要记住,当存储在数据库中时,文件中的原始代码只不过是一个美化的字符串,除非您动态添加内联元数据。它只是文本,并且进行标准转义将使其以任何格式作为字符串(在"或"内)安全地存储在JSON中。

我建议阅读这个SO答案,因为我也参考了它来验证我已经认为是正确的:如何使用JavaScript转义包含换行字符的JSON字符串