---
title: "中间件"
version: 6.0
locale: zh-hans
source: https://docs.djangoproject.com/zh-hans/6.0/ref/middleware/
canonical: https://djangodocs.dev/zh-hans/6.0/ref/middleware/
---
# 中间件

这篇文档解释了所有 Django 自带的中间件组件。关于如何使用它们以及如何编写自己的中间件，请参见 [中间件使用指南](/zh-hans/6.0/topics/http/middleware/)。

## 可用的中间件

### 缓存中间件

#### `class UpdateCacheMiddleware`

#### `class FetchFromCacheMiddleware`

启用全站缓存。如果启用了这些功能，那么每一个 Django 驱动的页面都会在 [`CACHE_MIDDLEWARE_SECONDS`](/zh-hans/6.0/ref/settings/#std-setting-CACHE_MIDDLEWARE_SECONDS) 配置定义的时间内被缓存。参见 [缓存文档](/zh-hans/6.0/topics/cache/)。

### “通用”中间件

#### `class CommonMiddleware`

#### `response_redirect_class`

默认为 [`HttpResponsePermanentRedirect`](/zh-hans/6.0/ref/request-response/#django.http.HttpResponsePermanentRedirect)。子类化 `CommonMiddleware`，并重写该属性来定制中间件发出的重定向。

为完美主义者增加了一些便利：

- 禁止 [`DISALLOWED_USER_AGENTS`](/zh-hans/6.0/ref/settings/#std-setting-DISALLOWED_USER_AGENTS) 配置中的用户代理访问，它应该是一个编译的正则表达式对象列表。
- 根据 [`APPEND_SLASH`](/zh-hans/6.0/ref/settings/#std-setting-APPEND_SLASH) 和 [`PREPEND_WWW`](/zh-hans/6.0/ref/settings/#std-setting-PREPEND_WWW) 的配置进行 URL 重写。

  如果 [`APPEND_SLASH`](/zh-hans/6.0/ref/settings/#std-setting-APPEND_SLASH) 为 `True`，并且初始的 URL 没有以斜线结尾，而且在 URLconf 中也没有找到，那么就会在最后附加一个斜线形成一个新的 URL。如果在 URLconf 中找到了这个新的 URL，那么 Django 会将请求重定向到这个新的 URL。否则，初始的 URL 就会被照常处理。

  例如，`foo.com/bar` 将被重定向到 `foo.com/bar/`，如果你没有 `foo.com/bar` 的有效 URL 模式，但 *有* `foo.com/bar/` 的有效模式。

  如果 [`PREPEND_WWW`](/zh-hans/6.0/ref/settings/#std-setting-PREPEND_WWW) 为 `True`，缺乏前导“www. ”的 URL 将被重定向到带有前导“www. ”的同一 URL。

  这两个选项都是为了规范 URL。其理念是，每个 URL 应该存在于一个地方，而且只有一个地方。从技术上讲，URL `foo.com/bar` 与 `foo.com/bar/` 是不同的——搜索引擎索引器会将它们视为单独的 URL——所以最好的做法是将 URL 规范化。

  如果有必要，可以使用 [`no_append_slash()`](/zh-hans/6.0/topics/http/decorators/#django.views.decorators.common.no_append_slash) 装饰器将个别视图从 `APPEND_SLASH` 行为中排除：

  ```
  from django.views.decorators.common import no_append_slash

  @no_append_slash
  def sensitive_fbv(request, *args, **kwargs):
      """View to be excluded from APPEND_SLASH."""
      return HttpResponse()
  ```
- 设置非流响应的 `Content-Length` 头。

#### `class BrokenLinkEmailsMiddleware`

- 向 `manager` 发送失效链接通知邮件（参见 [如何管理错误报告](/zh-hans/6.0/howto/error-reporting/)）。

### GZip 中间件

#### `class GZipMiddleware`

#### `max_random_bytes`

默认为 100。如果需要更改包含在压缩响应中的最大随机字节数，请子类化 `GZipMiddleware` 并重写该属性。

> **Note**
>
> 安全研究人员揭示了当在网站上使用压缩技术（包括 `GZipMiddleware`）时，该网站可能会暴露于多种可能的攻击。
>
> 为了减轻攻击风险，Django 实施了一种称为 *Heal The Breach (HTB)* 的技术。它在每个响应中添加了最多 100 字节（参见 [`max_random_bytes`](#django.middleware.gzip.GZipMiddleware.max_random_bytes)）的随机字节，以减弱攻击的效果。
>
> 有关更多详细信息，请参阅 [BREACH 论文 (PDF)](https://www.breachattack.com/resources/BREACH%20-%20SSL,%20gone%20in%2030%20seconds.pdf)、[breachattack.com](https://www.breachattack.com/) 和 [Heal The Breach (HTB) 论文](https://ieeexplore.ieee.org/document/9754554)。

`django.middleware.gzip.GZipMiddleware` 为能理解 GZip 压缩的浏览器（所有现代浏览器）压缩内容。

这个中间件应该放在任何其他需要读取或写入响应体的中间件之前，这样压缩就会在之后发生。

如果以下任何一项为真，它将不会压缩内容：

- 内容主体长度小于 200 字节。
- 响应已经设置了 `Content-Encoding` 头。
- 请求（浏览器）没有发送包含 `gzip` 的 `Accept-Encoding` 头。

如果响应具有 `ETag` 标头，则会将 ETag 标记为弱标记，以符合 [**RFC 9110 Section 8.8.1**](https://datatracker.ietf.org/doc/html/rfc9110.html#section-8.8.1)。

You can apply GZip compression to individual views using the
[`gzip_page()`](/zh-hans/6.0/topics/http/decorators/#django.views.decorators.gzip.gzip_page) decorator.

### 条件 GET 中间件

#### `class ConditionalGetMiddleware`

处理有条件的 GET 操作。如果响应没有 `ETag` 头，中间件会根据需要添加一个。如果响应有 `ETag` 或 `Last-Modified` 头，而请求有 `If-None-Match` 或 `If-Modified-Since`，则响应被一个 [`HttpResponseNotModified`](/zh-hans/6.0/ref/request-response/#django.http.HttpResponseNotModified) 替换。

You can handle conditional GET operations with individual views using the
[`conditional_page()`](/zh-hans/6.0/topics/http/decorators/#django.views.decorators.http.conditional_page) decorator.

### 本地化中间件

#### `class LocaleMiddleware`

#### `response_redirect_class`

默认为 [`HttpResponseRedirect`](/zh-hans/6.0/ref/request-response/#django.http.HttpResponseRedirect)。子类化 `LocaleMiddleware` 并重写该属性，以自定义中间件发出的重定向。

可以根据请求的数据选择语言。它为每个用户定制内容。请参阅 [国际化文档](/zh-hans/6.0/topics/i18n/translation/)。

### 消息中间件

#### `class MessageMiddleware`

启用基于 cookie 和会话的消息支持。参见 [消息文档](/zh-hans/6.0/ref/contrib/messages/)。

### 安全中间件

> **Warning**
>
> 如果您的部署情况允许，通常是一个好主意让您的前端 Web 服务器执行由 `SecurityMiddleware` 提供的功能。这样，如果有不由 Django 处理的请求（如静态媒体或用户上传的文件），它们将具有与请求到您的 Django 应用程序相同的保护。

#### `class SecurityMiddleware`

`django.middleware.security.SecurityMiddleware` 为请求／响应周期提供了若干安全增强功能。每一项都可以通过设置独立地启用或禁用。

- [`SECURE_CONTENT_TYPE_NOSNIFF`](/zh-hans/6.0/ref/settings/#std-setting-SECURE_CONTENT_TYPE_NOSNIFF)
- [`SECURE_CROSS_ORIGIN_OPENER_POLICY`](/zh-hans/6.0/ref/settings/#std-setting-SECURE_CROSS_ORIGIN_OPENER_POLICY)
- [`SECURE_HSTS_INCLUDE_SUBDOMAINS`](/zh-hans/6.0/ref/settings/#std-setting-SECURE_HSTS_INCLUDE_SUBDOMAINS)
- [`SECURE_HSTS_PRELOAD`](/zh-hans/6.0/ref/settings/#std-setting-SECURE_HSTS_PRELOAD)
- [`SECURE_HSTS_SECONDS`](/zh-hans/6.0/ref/settings/#std-setting-SECURE_HSTS_SECONDS)
- [`SECURE_REDIRECT_EXEMPT`](/zh-hans/6.0/ref/settings/#std-setting-SECURE_REDIRECT_EXEMPT)
- [`SECURE_REFERRER_POLICY`](/zh-hans/6.0/ref/settings/#std-setting-SECURE_REFERRER_POLICY)
- [`SECURE_SSL_HOST`](/zh-hans/6.0/ref/settings/#std-setting-SECURE_SSL_HOST)
- [`SECURE_SSL_REDIRECT`](/zh-hans/6.0/ref/settings/#std-setting-SECURE_SSL_REDIRECT)

#### HTTP 严格传输安全

对于只能通过 HTTPS 访问的网站，你可以通过设置 ["Strict-Transport-Security" 头](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security) 来指示现代浏览器拒绝通过不安全的连接连接到你的域名（在给定的时间内）。这可以减少你受到一些 SSL 剥离中间人（MITM）的攻击。

如果你将 [`SECURE_HSTS_SECONDS`](/zh-hans/6.0/ref/settings/#std-setting-SECURE_HSTS_SECONDS) 设置为一个非零的整数值，`SecurityMiddleware` 将为你在所有 HTTPS 响应中设置这个头。

启用 HSTS 时，建议首先使用一个小的测试值，例如，将 [`SECURE_HSTS_SECONDS = 3600`](/zh-hans/6.0/ref/settings/#std-setting-SECURE_HSTS_SECONDS) 设置为一小时。每次 Web 浏览器看到来自您网站的 HSTS 标头时，它将拒绝在给定的时间段内与您的域名进行非安全通信（使用 HTTP）。一旦您确认您的网站上的所有资源都以安全方式提供（即 HSTS 没有引发任何问题），则建议增加此值，以便不经常访问的访问者也受到保护（常见的值是 31536000 秒，即 1 年）。

此外，如果你将 [`SECURE_HSTS_INCLUDE_SUBDOMAINS`](/zh-hans/6.0/ref/settings/#std-setting-SECURE_HSTS_INCLUDE_SUBDOMAINS) 设置为 `True`，`SecurityMiddleware` 将在 `Strict-Transport-Security` 头中添加 `includeSubDomains` 指令。建议这样做（假设所有的子域都只使用 HTTPS 服务），否则你的网站仍然可能通过不安全的连接到子域而受到攻击。

如果你希望将你的网站提交到 [浏览器预加载列表](https://hstspreload.org/) ，请将 [`SECURE_HSTS_PRELOAD`](/zh-hans/6.0/ref/settings/#std-setting-SECURE_HSTS_PRELOAD) 设置为 `True`。这样就会把 `preload` 指令附加到 `Strict-Transport-Security` 头。

> **Warning**
>
> HSTS 策略适用于你的整个域，而不仅仅是你设置响应头的 URL。因此，你应该只在你的整个域名只通过 HTTPS 服务时使用它。
>
> 适当尊重 HSTS 头的浏览器将拒绝允许用户绕过警告，并连接到使用过期、自签名或其他无效 SSL 证书的网站。如果你使用 HSTS，请确保你的证书处于良好状态，并保持这种状态！

> **Note**
>
> 如果你部署在负载平衡器或反向代理服务器后面，而 `Strict-Transport-Security` 头没有被添加到你的响应中，这可能是因为 Django 没有意识到它是在一个安全的连接上；你可能需要设置 [`SECURE_PROXY_SSL_HEADER`](/zh-hans/6.0/ref/settings/#std-setting-SECURE_PROXY_SSL_HEADER) 设置。

#### Referrer 政策

浏览器使用 [referer 头](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer) 作为向网站发送关于用户如何到达那里的信息的一种方式。当用户点击一个链接时，浏览器将发送链接页面的完整 URL 作为 referrer。虽然这对某些目的来说可能很有用——例如查明谁在链接到你的网站——但它也可能引起隐私问题，因为它告诉一个网站，一个用户正在访问另一个网站。

一些浏览器能够接受关于是否应该在用户点击链接时发送 HTTP `Referer` 头的提示；这种提示通过 [Referrer-Policy 头](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy) 提供。这个头可以向浏览器建议三种行为中的任何一种：

- 完整 URL：在 `Referer` 头中发送整个URL。例如，如果用户访问 `https://example.com/page.html`，`Referer` 头将包含 `"https://example.com/page.html"`。
- 仅起源：只发送 referrer 中的“起源”。起源由方案、主机和（可选）端口号组成。例如，如果用户访问的是 `https://example.com/page.html`，起源就是 `https://example.com/`。
- 无 referrer：完全不发送 `Referer` 头。

有两种类型的情况，这个头可以告诉浏览器要注意：

- 同源与跨源：从 `https://example.com/1.html` 到 `https://example.com/2.html` 的链接为同源链接。从 `https://example.com/page.html` 到 `https://not.example.com/page.html` 的链接为跨源链接。
- 协议降级：如果包含链接的页面是通过 HTTPS 服务的，但被链接的页面不是通过 HTTPS 服务的，就会发生降级。

> **Warning**
>
> 当您的网站通过 HTTPS 提供服务时，[Django 的 CSRF 保护系统](/zh-hans/6.0/ref/csrf/#how-csrf-works) 需要存在 `Referer` 标头，因此完全禁用 `Referer` 标头将干扰 CSRF 保护。为了获得禁用 `Referer` 标头的大部分好处，同时保留 CSRF 保护，请考虑仅启用同源引用。

`SecurityMiddleware` 可以根据 [`SECURE_REFERRER_POLICY`](/zh-hans/6.0/ref/settings/#std-setting-SECURE_REFERRER_POLICY) 设置，为你设置 `Referrer-Policy` 头（注意拼写：当用户点击链接时，浏览器会发送一个 `Referer` 头，但指示浏览器是否这样做的头是拼写为 `Referrer-Policy`）。该设置的有效值为：

**`no-referrer`**

  指示浏览器对在本网站上点击的链接不发送 referrer。

**`no-referrer-when-downgrade`**

  指示浏览器发送完整的 URL 作为 referrer，但只有在没有发生协议降级的情况下。

**`origin`**

  指示浏览器只发送起源，而不是完整的 URL 作为 referrer。

**`origin-when-cross-origin`**

  指示浏览器发送完整的 URL 作为同源链接的 referrer，而只发送起源给跨源链接。

`same-origin` Instructs the browser to send a full URL, but only for
same-origin links. No referrer will be sent for cross-origin links.

`strict-origin` Instructs the browser to send only the origin, not the full
URL, and to send no referrer when a protocol downgrade occurs.

**`strict-origin-when-cross-origin`**

  当链接为同源且不发生协议降级时，指示浏览器发送完整的 URL；当链接为跨源且不发生协议降级时，只发送起源；当发生协议降级时，不发送 referrer。

**`unsafe-url`**

  指示浏览器始终发送完整的 URL 作为 referrer。

> **未知政策值**
>
> 当一个策略值被用户代理认为 [未知](https://w3c.github.io/webappsec-referrer-policy/#unknown-policy-values) 时，可以指定多个策略值以提供后备。最后一个被理解的指定值优先。为了支持这一点，可以在 [`SECURE_REFERRER_POLICY`](/zh-hans/6.0/ref/settings/#std-setting-SECURE_REFERRER_POLICY) 中使用一个可迭代对象或逗号分隔的字符串。

#### 跨域开启策略

一些浏览器可以通过根据 [Cross-Origin Opener Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Opener-Policy) （COOP）标头的值将顶级窗口与其他文档隔离开来，将它们放入单独的浏览上下文组中。如果以这种方式隔离的文档打开一个跨源弹出窗口，弹出窗口的 `window.opener` 属性将为 `null`。使用 COOP 隔离窗口是一种深度防御，可有效防止跨源攻击，特别是像 Spectre 这样允许数据泄漏到共享浏览上下文中的攻击。

`SecurityMiddleware` 可以根据 [`SECURE_CROSS_ORIGIN_OPENER_POLICY`](/zh-hans/6.0/ref/settings/#std-setting-SECURE_CROSS_ORIGIN_OPENER_POLICY) 设置为您设置 `Cross-Origin-Opener-Policy` 标头。此设置的有效值包括：

**`same-origin`**

  将浏览上下文专门隔离为同源文档。不会在同一浏览上下文中加载跨源文档。这是默认和最安全的选项。

**`same-origin-allow-popups`**

  将浏览上下文隔离为同源文档或那些不设置 COOP 或通过设置 COOP 为 `unsafe-none` 来选择退出隔离的文档。

**`unsafe-none`**

  允许文档被添加到其打开者的浏览上下文组，除非打开者本身具有 COOP 为 `same-origin` 或 `same-origin-allow-popups` 的设置。

#### `X-Content-Type-Options: nosniff`

一些浏览器会试图猜测它们获取的资源的内容类型，覆盖 `Content-Type` 头。虽然这可以帮助显示配置不当的服务器的网站，但也会带来安全风险。

如果你的网站提供用户上传的文件，恶意用户可能会上传一个特制的文件，当你认为它是无害的东西时，该文件会被浏览器解释为 HTML 或 JavaScript。

To prevent the browser from guessing the content type and force it to
always use the type provided in the `Content-Type` header, you can pass
the [X-Content-Type-Options: nosniff](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options) header. `SecurityMiddleware` will
do this for all responses if the [`SECURE_CONTENT_TYPE_NOSNIFF`](/zh-hans/6.0/ref/settings/#std-setting-SECURE_CONTENT_TYPE_NOSNIFF) setting
is `True`.

请注意，在大多数部署情况下，如果 Django 不涉及提供用户上传的文件，这个设置不会对您有所帮助。例如，如果您的 [`MEDIA_URL`](/zh-hans/6.0/ref/settings/#std-setting-MEDIA_URL) 直接由您的前端 Web 服务器（nginx、Apache 等）提供服务，那么您需要在那里设置此标头。另一方面，如果您正在使用 Django 来执行某些操作，比如要求授权以下载文件，并且无法在 Web 服务器中设置标头，那么这个设置将会有用。

#### SSL 重定向

如果你的网站同时提供 HTTP 和 HTTPS 连接，大多数用户最终会默认使用不安全的连接。为了达到最佳的安全性，你应该将所有的 HTTP 连接重定向到 HTTPS。

如果你将 [`SECURE_SSL_REDIRECT`](/zh-hans/6.0/ref/settings/#std-setting-SECURE_SSL_REDIRECT) 设置为 True，`SecurityMiddleware` 将永久（HTTP 301）重定向所有 HTTP 连接到 HTTPS。

> **Note**
>
> 出于性能方面的考虑，最好在 Django 之外，在前端负载均衡器或反向代理服务器（如 [nginx](https://nginx.org/) ）中做这些重定向。 [`SECURE_SSL_REDIRECT`](/zh-hans/6.0/ref/settings/#std-setting-SECURE_SSL_REDIRECT) 是为了在部署情况下，这不是一个选项。

如果 [`SECURE_SSL_HOST`](/zh-hans/6.0/ref/settings/#std-setting-SECURE_SSL_HOST) 设置有一个值，所有的重定向将被发送到该主机，而不是最初要求的主机。

如果你的网站上有几个页面应该通过 HTTP 提供，而不是重定向到 HTTPS，你可以在 [`SECURE_REDIRECT_EXEMPT`](/zh-hans/6.0/ref/settings/#std-setting-SECURE_REDIRECT_EXEMPT) 设置中列出正则表达式来匹配这些 URL。

> **Note**
>
> 如果你部署在负载均衡器或反向代理服务器后面，而 Django 似乎无法判断一个请求是否真的已经安全，你可能需要设置 [`SECURE_PROXY_SSL_HEADER`](/zh-hans/6.0/ref/settings/#std-setting-SECURE_PROXY_SSL_HEADER) 配置。

### 会话中间件

#### `class SessionMiddleware`

启用会话支持。参见 [会话文档](/zh-hans/6.0/topics/http/sessions/)。

### 站点中间件

#### `class CurrentSiteMiddleware`

将代表当前站点的 `site` 属性添加到每个传入的 `HttpRequest` 对象中。参见 [站点文档](/zh-hans/6.0/ref/contrib/sites/#site-middleware)。

### 验证中间件

#### `class AuthenticationMiddleware`

将 `user` 属性添加到每个传入的 `HttpRequest` 对象中，表示当前已登录的用户。请参阅 [Web 请求中的身份验证](/zh-hans/6.0/topics/auth/default/#auth-web-requests)。

#### `class LoginRequiredMiddleware`

子类化中间件并覆盖以下属性和方法以自定义未认证请求的行为。

#### `redirect_field_name`

默认为 `"next"`。

#### `get_login_url()`

返回未认证请求将重定向到的 URL。此结果是 [`login_required()`](/zh-hans/6.0/topics/auth/default/#django.contrib.auth.decorators.login_required) 装饰器上设置的 ```login_url``（如果不是 ``None```），或 [`settings.LOGIN_URL`](/zh-hans/6.0/ref/settings/#std-setting-LOGIN_URL)。

#### `get_redirect_field_name()`

返回包含用户成功登录后应重定向到的 URL 的查询参数的名称。此结果是 [`login_required()`](/zh-hans/6.0/topics/auth/default/#django.contrib.auth.decorators.login_required) 装饰器上设置的 ```redirect_field_name``（如果不是 ``None```），或 [`redirect_field_name`](#django.contrib.auth.middleware.LoginRequiredMiddleware.redirect_field_name)。如果返回 `None`，则不会添加查询参数。

将所有未认证请求重定向到登录页面，除了使用 [`login_not_required()`](/zh-hans/6.0/topics/auth/default/#django.contrib.auth.decorators.login_not_required) 排除的视图。登录页面默认为 [`settings.LOGIN_URL`](/zh-hans/6.0/ref/settings/#std-setting-LOGIN_URL)，但可以自定义。

通过将其添加到 [`MIDDLEWARE`](/zh-hans/6.0/ref/settings/#std-setting-MIDDLEWARE) 设置中 **之后** [`AuthenticationMiddleware`](#django.contrib.auth.middleware.AuthenticationMiddleware) 来启用此中间件：

```
MIDDLEWARE = [
    "...",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django.contrib.auth.middleware.LoginRequiredMiddleware",
    "...",
]
```

使用 [`login_not_required()`](/zh-hans/6.0/topics/auth/default/#django.contrib.auth.decorators.login_not_required) 使视图公开，允许未认证请求。例如：

```
from django.contrib.auth.decorators import login_not_required

@login_not_required
def contact_us(request): ...
```

使用 [`login_required()`](/zh-hans/6.0/topics/auth/default/#django.contrib.auth.decorators.login_required) 装饰器自定义认证视图的登录 URL 或字段名称，分别设置 `login_url` 或 `redirect_field_name`。例如：

```
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
from django.views.generic import View

@login_required(login_url="/books/login/", redirect_field_name="redirect_to")
def book_dashboard(request): ...

@method_decorator(
    login_required(login_url="/books/login/", redirect_field_name="redirect_to"),
    name="dispatch",
)
class BookMetrics(View):
    pass
```

> **确保你的登录视图不需要登录。**
>
> 为了防止无限重定向，请确保你已 [启用未认证请求](/zh-hans/6.0/topics/auth/default/#disable-login-required-middleware-for-views) 到你的登录视图。

#### `class RemoteUserMiddleware`

Middleware for utilizing web server provided authentication. See
[使用 REMOTE\_USER 进行身份验证](/zh-hans/6.0/howto/auth-remote-user/) for usage details, including security
considerations.

#### `class PersistentRemoteUserMiddleware`

Middleware for utilizing web server provided authentication when enabled only
on the login page. See [仅在登录界面使用 REMOTE\_USER](/zh-hans/6.0/howto/auth-remote-user/#persistent-remote-user-middleware-howto) for usage
details, including security considerations.

### CSRF 保护中间件

#### `class CsrfViewMiddleware`

通过在 POST 表单中添加隐藏的表单字段，并检查请求的正确值，增加对跨站点伪造请求的保护。请参阅 [跨站点伪造请求保护文档](/zh-hans/6.0/ref/csrf/)。

You can add Cross Site Request Forgery protection to individual views using the
[`csrf_protect()`](/zh-hans/6.0/ref/csrf/#django.views.decorators.csrf.csrf_protect) decorator.

### `X-Frame-Options` 中间件

#### `class XFrameOptionsMiddleware`

简单的 [通过 X-Frame-Options 头的点击劫持保护](/zh-hans/6.0/ref/clickjacking/)。

### Content Security Policy middleware

#### `class ContentSecurityPolicyMiddleware`

> **New in Django 6.0**

Adds support for Content Security Policy (CSP), which helps mitigate risks such
as Cross-Site Scripting (XSS) and data injection attacks by controlling the
sources of content that can be loaded in the browser. See the
[概况](/zh-hans/6.0/ref/csp/#csp-overview) documentation for details on configuring policies.

This middleware sets the following headers on the response depending on the
available settings:

- `Content-Security-Policy`, based on [`SECURE_CSP`](/zh-hans/6.0/ref/settings/#std-setting-SECURE_CSP).
- `Content-Security-Policy-Report-Only`, based on
  [`SECURE_CSP_REPORT_ONLY`](/zh-hans/6.0/ref/settings/#std-setting-SECURE_CSP_REPORT_ONLY).

## 中间件顺序

下面是关于各种 Django 中间件类的排序的一些提示：

1. [`SecurityMiddleware`](#django.middleware.security.SecurityMiddleware)

   如果你要开启 SSL 重定向，它应该排在列表的最前面，因为这样可以避免运行一堆其他不必要的中间件。
2. [`UpdateCacheMiddleware`](#django.middleware.cache.UpdateCacheMiddleware)

   在修改 `Vary` 头（`SessionMiddleware`、`GZipMiddleware`、`LocaleMiddleware`）之前。
3. [`GZipMiddleware`](#django.middleware.gzip.GZipMiddleware)

   在任何可能改变或使用响应体的中间件之前。

   在 `UpdateCacheMiddleware` 之后：修改 `Vary` 头。
4. [`SessionMiddleware`](#django.contrib.sessions.middleware.SessionMiddleware)

   在任何可能引发异常触发错误视图的中间件之前（如 [`PermissionDenied`](/zh-hans/6.0/ref/exceptions/#django.core.exceptions.PermissionDenied)），如果你使用的是 [`CSRF_USE_SESSIONS`](/zh-hans/6.0/ref/settings/#std-setting-CSRF_USE_SESSIONS)。

   在 `UpdateCacheMiddleware` 之后：修改 `Vary` 头。
5. [`ConditionalGetMiddleware`](#django.middleware.http.ConditionalGetMiddleware)

   在任何可能改变响应的中间件之前（它设置 `ETag` 头）。

   在 `GZipMiddleware` 之后，这样它就不会在 gzip 压缩后的内容上计算 `ETag` 头。
6. [`LocaleMiddleware`](#django.middleware.locale.LocaleMiddleware)

   最上面的一个，仅次于 `SessionMiddleware` （使用会话数据）和 `UpdateCacheMiddleware` （修改 `Vary` 头）。
7. [`CommonMiddleware`](#django.middleware.common.CommonMiddleware)

   在任何可能改变响应的中间件之前（它设置 `Content-Length` 头）。出现在 `CommonMiddleware` 之前并改变响应的中间件必须重置 `Content-Length`。

   靠近顶部：当 [`APPEND_SLASH`](/zh-hans/6.0/ref/settings/#std-setting-APPEND_SLASH) 或 [`PREPEND_WWW`](/zh-hans/6.0/ref/settings/#std-setting-PREPEND_WWW) 设置为 `True` 时，它会重定向。

   在 `SessionMiddleware` 之后，如果你使用 [`CSRF_USE_SESSIONS`](/zh-hans/6.0/ref/settings/#std-setting-CSRF_USE_SESSIONS)。
8. [`CsrfViewMiddleware`](#django.middleware.csrf.CsrfViewMiddleware)

   在任何假设 CSRF 攻击已经被处理的视图中间件之前。

   在 [`RemoteUserMiddleware`](#django.contrib.auth.middleware.RemoteUserMiddleware)，或任何其他可能执行登录的认证中间件，从而旋转 CSRF 令牌，然后再向下调用中间件链。

   在 `SessionMiddleware` 之后，如果你使用 [`CSRF_USE_SESSIONS`](/zh-hans/6.0/ref/settings/#std-setting-CSRF_USE_SESSIONS)。
9. [`AuthenticationMiddleware`](#django.contrib.auth.middleware.AuthenticationMiddleware)

   `SessionMiddleware` 之后：使用会话存储。
10. [`LoginRequiredMiddleware`](#django.contrib.auth.middleware.LoginRequiredMiddleware)

    在 `AuthenticationMiddleware` 之后：使用用户对象。
11. [`MessageMiddleware`](#django.contrib.messages.middleware.MessageMiddleware)

    `SessionMiddleware` 之后：可以使用基于会话的存储。
12. [`FetchFromCacheMiddleware`](#django.middleware.cache.FetchFromCacheMiddleware)

    在任何修改 `Vary` 头的中间件之后：该头用于为缓存哈希键选取一个值。
13. [`ContentSecurityPolicyMiddleware`](#django.middleware.csp.ContentSecurityPolicyMiddleware)

    Can be placed near the bottom, but ensure any middleware that accesses
    [csp\_nonce](/zh-hans/6.0/ref/csp/#csp-nonce) is positioned after it, so the nonce is
    properly included in the response header.
14. [`FlatpageFallbackMiddleware`](/zh-hans/6.0/ref/contrib/flatpages/#django.contrib.flatpages.middleware.FlatpageFallbackMiddleware)

    应该是接近底部，因为这是一种最后的中间件。
15. [`RedirectFallbackMiddleware`](/zh-hans/6.0/ref/contrib/redirects/#django.contrib.redirects.middleware.RedirectFallbackMiddleware)

    应该是接近底部，因为这是一种最后的中间件。
