【问题标题】:Alternative to query string and cookies when sending data to server?向服务器发送数据时查询字符串和 cookie 的替代方案?
【发布时间】:2009-07-28 15:57:36
【问题描述】:

对于我从事的产品,我在一些 ASP.NET/Castle Monorail 网站上遇到了一个小问题(或者可能不是那么小)。这是一个相当遗留的系统(写得早于我的时间),它使用 GET 请求,并在查询字符串中包含大量信息。我们最近遇到了查询字符串长度限制,对于我们需要传输到服务器的数据量,将数据临时存储在 cookie 中也是不合理的(我们已经远远超过了每个 cookie 4096 字节的限制,而且我们设置了很多 cookie,因此我们可能也接近或处于每个域的 cookie 限制。)

我想知道除了 POST(在某些情况下可以更改为 POST 请求,但可能不是全部)之外,是否有任何替代方法可以解决此问题。我希望 StackOverflow 上的其他人也遇到过类似的问题,并且有一些神奇的解决方案(即使用 javascript 压缩数据,编码为 base64,传递给单个查询字符串项?只是不确定是否有任何库可以压缩以与 .NET 3.5 中的内置压缩类兼容的方式使用 javascript 处理数据。)

更新:

我最终选择的解决方案是 POST 到临时控制器。这个临时控制器拉取大量数据,将其卡在共享会话中(生产服务器位于不使用粘性会话/IP 的大型多银行服务器场中),并对实际控制器执行 GET,后者拉取来自共享会话的数据。不是最高效的解决方案,但它解决了问题。

【问题讨论】:

  • 请解释为什么您不能发布。恕我直言,这里唯一真正的解决方案是发布。
  • 使用 POST 是有意义的,所以使用它。
  • 我正在使用的代码最终包含了许多用 VB6 和 COM 对象编写的旧代码。如果它只是新代码,POST 可能是一种选择......如果它只是非常旧的遗留代码,实施 POST 将花费比我必须修复和交付的时间更长的时间。
  • 为什么需要更长的时间?这只是一种方法!
  • 我同意乔希的观点。如果是 Monorail 应用程序,那么处理 Web 请求是 Monorail 的责任,您可以轻松地将 GET 更改为 POST。

标签: .net asp.net javascript query-string castle-monorail


【解决方案1】:

有几个Base64 encode plugins for jQuery,但这无济于事,因为Base64 generally makes the data longer,而不是更短。

根据数据,我会研究其他一些文本压缩技术。 Wikipedia lists a few:

  • 上下文树加权法(CTW)
  • Burrows-Wheeler 变换(使压缩更高效的块排序预处理)
  • LZ77(由 DEFLATE 使用)
  • LZW

这是LZW implementation for Javascript

Huffman encoding 基于字母频率,因此它可能不适合您的数据。您可能必须对结果进行转义以使其成为 URL 安全的。

【讨论】:

  • 你知道 javascript 或 jQuery 的任何压缩算法吗?我可以找到其他一些编码,它是我真正感兴趣的压缩...
  • rumkin.com/tools/compression/compress_huff.php。看源码就可以看到代码了。
  • 约翰,我已经链接到那个(见霍夫曼编码的链接)。要记住的一件事是,霍夫曼使用英语中的标准字符频率工作,因此如果您的表单数据不是英文文本,它可能不是很有效。
【解决方案2】:

除了切换到 POST 之外,您的选择将受到限制。 Base64 将增加数据的大小而不是减少它。您提到将数据压缩为单个查询字符串项......也许您可以使用 Ajax 将数据拆分为 2 个单独的请求?不过,我不确定这是否适合您的情况。

【讨论】:

  • Ajax 在某些情况下可能是可能的。问题是有相当多的页面存在问题,并且每个页面都有不同的要求。感谢关于 base64 的提醒……我总是忘记它会使数据大小翻倍。 叹息
【解决方案3】:

如果像查询字符串这样生成数组,我建议使用 JSON 作为数据传输格式:

params[]=sth&params[]=sth2&params[]=sth3

这将是

{params:['sth1', 'sth2', 'sth3']}

您可以将此 JSON 字符串 sssign 到单个字母变量,如下所示

p={params:['sth1', 'sth2', 'sth3']}

更好的方法是对整个查询字符串进行压缩和 Base64 编码。由于您在服务器端生成查询字符串(我假设这可以通过使用相同的 comp/decomp 算法在 JS 中完成),您可以使用任何内置压缩算法和您的编程语言,例如 gzip。 Base64编码压缩后的数据,是的,它会扩大一点,但没有url编码扩大它。

【讨论】:

  • 感谢开箱即用的想法(这就是我一直在寻找的……开箱即用的想法。)将数据转换为 JSON 可以节省少量空间……但那是领先的我只是尽可能地简化它......所以我基本上得到了这个:p = 123234,123235,123237,288721,......仍然不是一个长期的解决方案(我想我仍然需要某种压缩/encoding),但在这个系统明年完全重写之前可能就足够了。
  • 正如我所说,一个更好的解决方案是 compress&base64。我们已经设法通过转换为 json -> compress -> base64 将 1700 个字符的 URL 字符串减少到 1000 个字符
  • 您使用了哪种压缩方式?我一直在搞乱其他人发布的霍夫曼算法,但是对于我拥有的数据,它不足以抵消编码扩展......
  • 好吧,我们在 JS 中需要该功能,所以我使用了 U-LZSS 库,它可以在 @Google Code 中找到。我不得不将它的解压器改成 PHP,但这没什么大不了的。如果它已经在 ASP.NET 中实现并且您不需要 JS,我建议使用 gzip。 LZSS 是 LZW 的一种变体,它可能不如基于 DEFLATE 的算法高效,但值得一试;)
  • 问题不在于速度,而在于创建的 URL 太长。网络上使用的 gzip 无法帮助我处理太长的 URL...我希望在发出请求之前做一些事情来缩短 URL 的长度。
【解决方案4】:

我不会过分依赖 javascript。压缩查询字符串将是第一件自然而然的事情;但如果你远远领先于这些限制,你应该尝试保持会话。您从默认状态信息重新开始,然后通过提供的 POST 数据逐渐将服务器上的状态反映到用户会话中,因此您将所有这些数据划分为许多处理程序(读取页面)。

【讨论】:

    【解决方案5】:

    教科书的答案是使用 POST。为什么这不可能?发明 POST 的原因几乎是为了绕过 GET 中的长度限制。

    根据细节的另一种可能性是有多个屏幕,每个屏幕都有一个数据子集,并将来自每个屏幕的数据存储在服务器上并在最后将它们连接起来。

    【讨论】:

    • 发明 POST 的原因不是为了绕过 GET 的长度限制。
    • “发明 POST 的原因几乎是为了绕过 GET 中的长度限制。”抱歉,当我读到这篇文章时,我笑死了。
    • 好吧,我愿意接受教育。为什么 POST 是当时发明的?是的,我知道从技术上讲 GET 应该用于幂等事务,而 POST 应该用于非幂等事务。但在现实生活中,它们之间的实际区别在于 GET 有严格的长度限制,而 POST 没有。在 JSP 中,GET 和 POST 的处理逻辑完全相同。您必须不遗余力地检查和区分它们。
    【解决方案6】:

    查询字符串限制在客户端还是服务端?

    如果问题只是客户端不会发送长 GET 字符串,也许您可​​以 POST 到代理服务器,然后将请求作为 GET 转发。

    【讨论】:

    【解决方案7】:

    这是保存页面之间的状态信息吗?如果是这样,一个选项可能是使用其值为 GUID 的 cookie:

    _SESSIONID=3F2504E0-4F89-11D3-9A0C-0305E82C3301
    

    并在服务器端存储会话信息。会话使用 GUID 唯一标识,因此可以轻松地直接在服务器上检索大量信息。

    然后,您需要在客户端发送/检索会话 ID 以及客户端生成的信息(GET/POST 字段)。

    【讨论】:

    • 它是一组在服务器端处理的大量 ID。
    • 好吧,一个由客户端连接的 SESSIONID。这就是 PHP 默认处理会话的方式,不会损失任何实际性能。由于传输较少,您的应用程序实际上会运行得更快。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-11
    • 1970-01-01
    相关资源
    最近更新 更多