【问题标题】:HTTP Response before Request请求前的 HTTP 响应
【发布时间】:2012-08-30 19:20:14
【问题描述】:

我的问题可能听起来很愚蠢,但我只是想确定一下:

  • 是否可以在请求该资源之前发送 HTTP 响应?

例如,假设您有一个 HTML 页面 index.html,它只显示一张名为 img.jpg 的图片。 现在,如果您的服务器知道访问者每次都会请求 HTML 文件,然后是 jpg 图像:

服务器是否可以在 HTML 文件之后发送图像以节省时间?

我知道 HTTP 是一个同步协议,所以理论上它不应该工作,但我只是希望有人确认(或不确认)。

【问题讨论】:

  • 那么您的问题是如何在 index.html 之后立即发送 JPEG 而无需等待浏览器呈现 html 页面并请求 JPEG?
  • 是的,完全正确。只是为已经确定的事情节省时间。就像为该特定页面加载哪些 CSS / JS 文件......等等。
  • HTTP/2 通过添加推送功能解决了这个问题;这需要服务器同时发送请求和相应的响应,允许客户端在本地缓存它。然后,当客户端请求资源时,它的本地缓存会满足它,不会产生网络通信。然而,在 HTTP/1.1 中,发送预测响应是非常不可取的。

标签: http networking tcp comet


【解决方案1】:

最近的post by Jacques Mattheij 引用了您的问题,声称虽然 HTTP 被设计为同步协议,但 实现 不是。实际上,浏览器(他没有具体说明是哪一个)接受尚未发送的请求的答案。

另一方面,如果你想找一些不那么老套的东西,你可以看看:

  • 允许服务器向浏览器发送内容的推送技术。取代长轮询/彗星“黑客”的现代实现是websockets。您可能还想看看socket.io
  • 或者您可能想查看client-side routing。一些实现将其与缓存技术结合在一起(我相信在derby.js 中)。

【讨论】:

  • 任何实现都会接受在请求读取之前发送的响应,但只有非常奇怪的实现才会在发送请求之前开始读取响应。
  • 确实很奇怪。并被帖子作者多次承认:“一点点黑魔法”,“游戏会结束,这次他们会堵住漏洞”,“我们很幸运它成功了,更幸运的是它一直在工作只要它做到了”。除了有趣之外,这也让阅读变得愉快。
【解决方案2】:

如果有人请求 /index.html,而您发送了两个响应(一个用于 /index.html,另一个用于 /img.jpg),您怎么知道收件人会收到这两个响应并知道如何处理它们在第二个请求进入之前?

问题不在于发送。问题在于接收器可能会收到意外数据。

另一个问题是您拒绝客户端使用 HTTP 缓存工具,如 If-Modified-Since 和 If-None-Match(即客户端可能不希望发送 /img.jpg,因为它已经有一个缓存副本)。

也就是说,您可以使用Comet 技术来近似服务器推送的好处。但这比简单地预测传入的 HTTP 请求要复杂得多。

【讨论】:

  • TCP 不是已经对较低级别的响应重新排序了吗?不过我不太了解缓存的问题。
【解决方案3】:

没有。 HTTP 被定义为请求/响应协议。一个请求:一个响应。其他任何东西都不是 HTTP,而是其他东西,您必须正确指定它并在两端完全实现它。

【讨论】:

  • HTTP 被定义为 request->response,但是完全可以在请求之前发送响应,这在视频流中被广泛用于发送下一帧而不等待请求。 jacquesmattheij.com/the-several-million-dollar-bug
  • @NickSweeting 我仍然会将其定义为 HTTP 以外的东西,或者基于 HTTP 构建的具有受限语义的东西(即 predicablt 请求)。它依赖于当前的实现而不是 HTTP 规范。在读取请求之前,实现甚至不可能知道响应已经发送,除非它当然是对不同请求的响应(这是该技术的基本问题),所以我发现作者对它的工作感到惊讶本身就相当惊人。
【解决方案4】:

我认为不可能在同一个 HTTP 响应中混合 .html 和图像。至于“立即”发送图像数据,在第一次请求之后 - 有一个“静态资源”的概念可能会有所帮助(但它需要客户为特定资源创建新的请求)。

article 中提到了一些有趣的事情。

【讨论】:

  • 没问题 - 请注意开发人员往往会忘记的最有趣的事情之一:由于上传和下载速度不对称,发送 0.5kb 的请求可能需要与下载更多千字节的请求一样多的时间来自服务器的数据。
【解决方案5】:

通过有效地缓存资源,您将获得更好的结果,即设置proper cache headers 并配置您的网络服务器进行缓存。您也可以inline images using base 64 encoding,如果这是一个具体问题。

您也可以查看long polling javascript 解决方案。

【讨论】:

  • 嗯,是的,缓存确实很有效,但它是一种单独的方法,可以减少从第一个请求到使用所有资源的全页面呈现之间的时间。缓存不会改变这样一个事实,即用户仍然需要执行请求,而且时间损失似乎无法减少。
  • 是的...然后看看内联资源...您可以在单个请求中包含几乎任何您想要的内容,方法是使其成为请求的 HTML 文档的一部分。
【解决方案6】:

您正在寻找 server push:它在 HTTP 中不可用。像 SPDY 这样的协议有它,但如果你被限制在 HTTP 上,那你就不走运了。

【讨论】:

    【解决方案7】:

    不,这是不可能的。

    请求的第一行包含被请求的资源,因此除非您首先检查请求的字节(至少一行的值),否则您不会知道要响应什么。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-28
      • 2020-11-17
      • 2023-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-24
      相关资源
      最近更新 更多