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

时间:2015-09-08 20:17:03

标签: javascript json ajax backbone.js xmlhttprequest

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

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

如果在IDE(例如Sublime)中打开文件,则可以查看和编辑包含该文件的实际代码。我试图将 THAT 原始内容放入JSON中,这样我就可以发送到浏览器,它可以被修改,然后发送回去。

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

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

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

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

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

3 个答案:

答案 0 :(得分:4)

AFAI担心简单的Base64转换会这样做。 Stringify,转换为base64,然后将其传递给服务器并在那里解码。然后你将没有原始文件传输,你仍然可以保持简单的代码。

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

所以问问自己,如果实施一个非常安全的解决方案会给用户带来很多麻烦,为什么还需要安全转移呢?基于此,我重申我之前所说的话。一个简单的Base64转换就行了。您还可以使用SHA256之类的其他算法来使它更安全。

答案 1 :(得分:4)

如果这里唯一关注的是代码文件的原始内容(&#34;数据&#34;您的模型正在存储),在存储在JSON中时会导致某种类型的问题,这很容易被<强>逃避您的数据。

对原始代码文件内容进行字符串化可能会导致问题,因为任何类似JavaScript或JSON的内容都将被解析为实际的JSON对象。 你的代码文件数据可以而且应该只是作为一个esacaped字符串存储。你担心的是,所述字符串可能包含可能会破坏存储在字符串中的JavaScript中的字符,这可以通过逃避整个字符串来缓解字符串,因而是双重,三重,四重等,转义已在代码文件中转义的任何内容。

从本质上讲,重要的是记住文件中的原始代码只是存储在数据库中的美化字符串,除非您动态添加内联元数据。它只是文本,并且进行标准转义可以安全地以任何格式存储为JSON中的字符串(内部&#34;&#34;或者#39;)。

我建议阅读这个SO答案,因为我也引用它来验证我认为正确的答案: How To Escape a JSON string containing newline characters using JavaScript

答案 2 :(得分:4)

有趣的问题。实现这一点所需的代码非常复杂,很抱歉我没有提供示例,但您似乎是一个体面的程序员,应该能够实现下面提到的内容。

关于通过JSON发送原始数据,您需要做的就是使JSON安全而不破坏您的代码是通过使用Python的json.dumps&amp; amp;中的stringyfying来逃避特殊字符。 JavaScript的JSON.stringyfy。 [1]

如果您担心某种形式的基本防篡改,那么除了让客户端和服务器传回每会话令牌之外,您的数据的轻量编码也符合目的。与JSON传输一起确保JSON不是从恶意地址伪造的。

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

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

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

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

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

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

您也可以使用multipart / form-data将数据发送到服务器,但我无法看到它是如何双向工作的。

<强>更新

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

发送数据

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

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

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

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

<强>接收

  • 从POST中抓取JSON

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

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

  • Z85解码接收到的JSON中的数据以获取原始数据,并根据需要存储在文件或数据库(服务器)或GUI / IDE(客户端)中的处理/显示中。

参考

[1] How to escape special characters in building a JSON string?

[2] Binary Data in JSON String. Something better than Base64

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

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

[5]用C / C ++ https://github.com/artemkin/z85

实现Z85

[6] https://gist.github.com/minrk/6357188

的Z85 Python实现

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

[8] JavaScript Gzip SO JavaScript implementation of Gzip