HTTP请求之前的响应

52

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

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

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

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

我知道HTTP是同步协议,理论上不应该起作用,但我只是想让某人确认一下(或不确认)。


那么你的问题是如何在等待浏览器呈现HTML页面并请求JPEG之前立即发送JPEG? - Tim M.
没错,就是为了节省时间而已,因为这些东西已经确定好了。比如说,加载哪些CSS/JS文件用于特定的页面...等等。 - m_vdbeek
HTTP/2通过添加推送功能来解决这个问题;这要求服务器同时发送请求和相应的响应,使客户端能够在本地缓存它。然后,当客户端请求资源时,它可以从本地缓存中满足,不需要进行网络通信。然而,在HTTP/1.1中,发送预测响应是极不可取的。 - avakar
7个回答

23
最近Jacques Mattheij发表的帖子提到了你所问的问题,称尽管HTTP被设计为同步协议,但其实现并不是。实际上,浏览器(他没有指定具体哪个浏览器)接受尚未发送的请求回答。
另一方面,如果您正在寻找一些更加专业的方法,可以考虑以下内容:
  • 推送技术:允许服务器向浏览器发送内容。取代长轮询/Comet“黑科技”的现代实现是websockets。您也可以查看socket.io
  • 或者,您可以查看客户端路由。有些实现结合了缓存技术(例如我认为在derby.js中)。

1
任何实现都将接受在请求被“读取”之前发送的响应,但只有相当奇怪的实现才会在发送请求之前开始读取响应。 - user207421
确实很奇怪。而且作者在文章中多次承认:“这是一点黑魔法”,“这次游戏结束了,他们会关闭漏洞”,“我们只是幸运地让它起作用,更幸运的是它能够持续工作这么长时间”。除了有趣之外,这也使得阅读变得愉快。 - nha

15
如果有人请求/index.html并且您发送了两个响应(一个是/index.html,另一个是/img.jpg),那么在第二个请求发出之前,您如何知道接收者将得到这两个响应并知道如何处理它们?
问题实际上不在于发送,而在于接收者可能会收到意外的数据。
另一个问题是,您正在拒绝客户端使用HTTP缓存工具,例如If-Modified-Since和If-None-Match(即客户端可能不希望发送/img.jpg,因为它已经有一个缓存副本)。
也就是说,您可以使用Comet技术来近似实现服务器推送的好处。但这比仅仅预测传入的HTTP请求要复杂得多。

TCP不是已经在较低层次上重新排序响应了吗?但我真的不理解缓存的问题。 - m_vdbeek

2
通过有效地缓存资源,即设置适当的缓存头并配置您的Web服务器进行缓存,您将获得更好的结果。如果这是一个具体的问题,您还可以使用base64编码来内联图像
您还可以查看长轮询 JavaScript 解决方案。

是的,缓存确实非常有效,但它是一种单独的方式来减少第一个请求和完整页面呈现所有资源之间的时间。缓存不会改变用户仍然需要发出请求的事实,这是似乎无法减少的时间损失。 - m_vdbeek
如果是真的,那么可以考虑内联资源...通过将其作为所请求的HTML文档的一部分来包含几乎任何想要的内容。 - Tim M.

1
你正在寻找服务器推送:它在HTTP中不可用。像SPDY这样的协议具有它,但如果你受限于HTTP,那么你就没有运气了。

1

我认为在同一个HTTP响应中混合.html和图像是不可能的。至于立即发送图像数据,紧接着第一个请求 - 有一个“静态资源”的概念可以帮助解决这个问题(但需要客户端为特定资源创建一个新的请求)。

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


不是问题-请注意开发人员经常忘记的最有趣的事情之一:由于上载和下载速度的不对称性,发送0.5kb请求可能需要与从服务器下载更多千字节的数据相同的时间。 - Maciek Talaska

-1

不,这是不可能的。

请求的第一行包含了被请求的资源,因此除非您先检查请求的字节(至少一个完整行),否则无法知道应该回复什么。


-2

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


1
HTTP被定义为请求->响应,但在视频流中,完全可以在请求之前发送响应,这在发送下一帧而无需等待请求时被广泛使用。http://jacquesmattheij.com/the-several-million-dollar-bug - Nick Sweeting
1
@NickSweeting 我仍然认为这不是HTTP,或者说它是建立在具有受限语义的HTTP之上(即可预测的请求)。它依赖于当前的实现,而不是HTTP规范。除非是针对不同请求的响应(这正是该技术的根本问题),否则实现甚至无法知道响应在读取请求之前是否已发送。因此,我对作者惊讶于其自身工作的惊奇感到惊讶。 - user207421

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接