Vary 标头定义了缓存机制在构建其缓存键时应考虑哪些请求标头。 例如,如果网页的内容取决于用户的语言偏好,则称该页面因语言而异。
默认情况下,Django 的缓存系统使用请求的完全合格的URL创建它的缓存密钥——例如,"https://www.example.com/stories/2005/?order_by=author"。这意味着对该 URL 的每个请求都将使用相同的缓存版本,而不管用户代理差异(如 cookies 或语言首选项)。但是,如果这个页面基于请求头(如 cookie、语言或用户代理)中的某些差异而产生不同的内容,则需要使用Vary标头来告诉缓存机制,页面输出取决于这些东西。
要在 Django 中执行此操作,请使用方便的 django.views.decorators.vary.vary_on_headers()
视图装饰器,像这样:
from django.views.decorators.vary import vary_on_headers
@vary_on_headers("User-Agent")
def my_view(request):
...
在这里,一个缓存机制(比如 Django 自带的缓存中间件)将为每一个唯一的用户代理缓存一个独立的页面版本。
使用 vary_on_headers
装饰器而不是手动设置 Vary 头(使用 response.headers["Vary"] = "user-agent"
)的好处是,装饰器 添加 到 Vary头(可能已经存在),而不是从头开始设置,可能会覆盖已经存在的东西。
你可以传递多个headers参数给 vary_on_headers()
:
@vary_on_headers("User-Agent", "Cookie")
def my_view(request):
...
这告诉下游缓存两者有所不同,意味着每个用户代理和 cookie 的组合将获取它自己的缓存值。比如,一个请求带有用户代理 Mozilla 和 cookie 值 foo=bar
被认为和用户代理 Mozilla 和 cookie 值 foo=ham
是不同的。
因为 cookie 的变化如此普遍,所以这里有个 django.views.decorators.vary.vary_on_cookie()
装饰器。这两个视图是等价的:
@vary_on_cookie
def my_view(request):
...
@vary_on_headers("Cookie")
def my_view(request):
...
传递给 vary_on_headers
的headers是不区分大小写的;User-Agent
和 user-agent
是一样的。
你也可以直接使用帮助函数 django.utils.cache.patch_vary_headers()
。这个函数可以设置或添加 Vary header
。比如:
from django.shortcuts import render
from django.utils.cache import patch_vary_headers
def my_view(request):
...
response = render(request, "template_name", context)
patch_vary_headers(response, ["Cookie"])
return response
patch_vary_headers
带有一个 HttpResponse
作为它的第一个参数,一个不区分大小写的头名的列表/元组作为它的第二个参数。
SWING - 控件每个用户界面考虑有以下三个主要方面:UI 元素: 有用户最终看到并且与之交互的核心视觉元素。GWT 提供了一个大量的...
以下是 JUnit 扩展CactusJWebUnitXMLUnitMockObjectCactusCactus 是一个简单框架用来测试服务器端的 Java 代码(Servlets, EJBs,...
动态SQL是MyBatis的强大特性之一。如果你使用过JDBC或其它类似的框架,你应该能理解根据不同条件拼接SQL语句有多痛苦,例如...
Spring 声明式事务管理声明式事务管理方法允许你在配置的帮助下而不是源代码硬编程来管理事务。这意味着你可以将事务管理从事务...
Servlet Session 跟踪HTTP 是一种"无状态"协议,这意味着每次客户端检索网页时,客户端打开一个单独的连接到 Web 服务器,服务器...
Swift 可选(Optionals)类型Swift 的可选(Optional)类型,用于处理值缺失的情况。可选表示"那儿有一个值,并且它等于 x "或者"...
盒语法和模式目前,唯一稳定可靠地方法就是通过 Box::new 方法来创建 Box。当然,它不可能在稳定的 Rust 来析构匹配模式下的 B...