【发布时间】:2013-12-13 02:43:06
【问题描述】:
我通过内容协商提供一组资源。
具体来说,任何 URL 都可以用不同的格式表示,
取决于客户端的 Accept 标头。
这方面的一个例子可以在 Facebook 上看到:
-
curl -H "Accept: application/json" http://graph.facebook.com/daft-punk
JSON 格式的结果 -
curl -H "Accept: text/turtle" http://graph.facebook.com/daft-punk
海龟的结果
我正在寻找基于 URL 和客户端的 Accept 标头缓存内容的 CDN。
问题示例
CloudFlare 不支持这一点:如果一个客户端请求 HTML,那么对该 URL 的所有后续请求都会收到 HTML 表示,而不管他们的偏好如何。 Others have similar issues.
例如,如果我将 CloudFlare 放置在 graph.facebook.com 上(并将其配置为缓存“无扩展”资源,默认情况下它不会这样做),那么它将行为不正确:
- 我通过 curl 在 JSON 中请求
http://graph.facebook.com/daft-punk;
作为响应,CloudFlare 会从服务器请求 JSON 原始文件,将其缓存并提供服务。 - 我通过浏览器请求
http://graph.facebook.com/daft-punk(因此是HTML);
作为响应,CloudFlare 会发送缓存的 JSON (!) 表示,即使原始服务器会发送 HTML 版本。
需要什么来代替
正确的行为是 CloudFlare 再次询问服务器,因为第二个客户端有不同的 Accept 标头。
在此之后,可以从缓存中提供具有相似 Accept 标头的请求。
哪些 CDN 解决方案支持内容协商,并且还缓存协商的内容?
所以请注意,仅尊重Accept 是不够的;协商的响应也应该被缓存。
PS1:很容易让您自己的缓存服务器支持它。例如,对于 nginx:
proxy_cache_key "$scheme$host$request_uri$http_accept";
请注意客户端的 Accept 标头如何成为索引缓存的键的一部分。我想要 CDN 上的那个。
PS2:不能为不同的表示使用不同的 URL。我的应用程序位于Linked Data 域中,其中 URL 起着重要的识别作用。
【问题讨论】:
-
我认为首先要修复的是 facebook 服务器标头。他们错过了
Vary: Accept,这会告诉缓存accept header会影响响应。 -
@neo 是的,但它仍然不适用于正确设置
Vary标头的服务器。
标签: http caching cdn cloudflare content-negotiation