协议

此页面包含 Inertia 协议的详细规范。请务必先阅读 工作原理 页面以获取高级概述。

HTML 响应

对 Inertia 应用的第一个请求只是一个普通的、完整的页面浏览器请求,没有特殊的 Inertia 标头或数据。对于这些请求,服务器返回一个完整的 HTML 文档。

此 HTML 响应包含网站资产(CSS、JavaScript)以及页面主体中的根 <div>。根 <div> 充当客户端应用程序的挂载点,并包含一个 data-page 属性,其中包含用于初始页面的 JSON 编码的 页面对象。Inertia 使用此信息来启动您的客户端框架并显示初始页面组件。

请求
GET: http://example.com/events/80
Accept: text/html, application/xhtml+xml
响应
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
<html>
<head>
    <title>My app</title>
    <link href="/css/app.css" rel="stylesheet">
    <script src="/js/app.js" defer></script>
</head>
<body>

<div id="app" data-page='{"component":"Event","props":{"event":{"id":80,"title":"Birthday party","start_date":"2019-06-02","description":"Come out and celebrate Jonathan&apos;s 36th birthday party!"}},"url":"/events/80","version":"c32b8e4965f418ad16eaebba1d4e960f"}'></div>

</body>
</html>
虽然初始响应是 HTML,但 Inertia 不会服务器端渲染 JavaScript 页面组件。

Inertia 响应

Inertia 应用启动后,对网站的所有后续请求都通过 XHR 进行,并设置 X-Inertia 标头为 true。此标头表示请求是由 Inertia 发出的,而不是标准的完整页面访问。

当服务器检测到 X-Inertia 标头时,它不会返回完整的 HTML 文档,而是返回一个 JSON 响应,其中包含一个编码的 页面对象

请求
GET: http://example.com/events/80
Accept: text/html, application/xhtml+xml
X-Requested-With: XMLHttpRequest
X-Inertia: true
X-Inertia-Version: 6b16b94d7c51cbe5b1fa42aac98241d5
响应
HTTP/1.1 200 OK
Content-Type: application/json
Vary: X-Inertia
X-Inertia: true
{
  "component": "Event",
  "props": {
    "event": {
      "id": 80,
      "title": "Birthday party",
      "start_date": "2019-06-02",
      "description": "Come out and celebrate Jonathan's 36th birthday party!"
    }
  },
  "url": "/events/80",
  "version": "c32b8e4965f418ad16eaebba1d4e960f"
}

页面对象

Inertia 通过页面对象在服务器和客户端之间共享数据。此对象包含渲染页面组件、更新浏览器历史记录状态和跟踪网站资产版本所需的信息。页面对象包含以下四个属性

  1. component: JavaScript 页面组件的名称。
  2. props: 页面道具(数据)。
  3. url: 页面 URL。
  4. version: 当前资产版本。

在标准的完整页面访问中,页面对象被 JSON 编码到根 <div> 中的 data-page 属性中。在 Inertia 访问中,页面对象作为 JSON 负载返回。

资产版本控制

单页应用程序的一个常见挑战是在更改网站资产后刷新它们。Inertia 通过可选地跟踪网站资产的当前版本来简化此操作。如果网站资产发生更改,Inertia 会自动进行完整的页面访问,而不是 XHR 访问。

Inertia 页面对象 包含一个 version 标识符。此版本标识符在服务器端设置,可以是数字、字符串、文件哈希或任何其他表示网站资产当前“版本”的值,只要该值在网站资产更新时发生变化即可。

每当进行 Inertia 请求时,Inertia 都会在 X-Inertia-Version 标头中包含当前资产版本。当服务器收到请求时,它会将 X-Inertia-Version 标头中提供的资产版本与当前资产版本进行比较。这通常在服务器端框架的中间件层中处理。

如果资产版本相同,请求将按预期继续。但是,如果资产版本不同,服务器会立即返回 409 Conflict 响应,并在 X-Inertia-Location 标头中包含 URL。此标头是必需的,因为可能发生了服务器端重定向。这告诉 Inertia 最终的预期目标 URL 是什么。

请注意,409 Conflict 响应仅针对 GET 请求发送,而不针对 POST/PUT/PATCH/DELETE 请求发送。也就是说,如果在这些请求之一之后发生 GET 重定向,它们将被发送。

如果在发生 409 Conflict 响应时存在“闪存”会话数据,Inertia 的服务器端框架适配器将自动重新闪存此数据。

请求
GET: http://example.com/events/80
Accept: text/html, application/xhtml+xml
X-Requested-With: XMLHttpRequest
X-Inertia: true
X-Inertia-Version: 6b16b94d7c51cbe5b1fa42aac98241d5
响应
409: 冲突
X-Inertia-Location: http://example.com/events/80

部分重新加载

在进行 Inertia 请求时,部分重新加载选项允许您在对相同页面组件的后续访问中从服务器请求道具(数据)的子集。如果某些页面数据变得陈旧是可以接受的,那么这可能是一个有用的性能优化。

当进行部分重新加载请求时,Inertia 会在请求中包含两个额外的标头:X-Inertia-Partial-DataX-Inertia-Partial-Component

The X-Inertia-Partial-Data 标头是一个逗号分隔的所需道具(数据)键列表,这些键应该被返回。

The X-Inertia-Partial-Component 标头包含正在部分重新加载的组件的名称。这是必需的,因为部分重新加载仅适用于对相同页面组件的请求。如果最终目标由于某种原因而不同(例如,用户已注销,现在位于登录页面),则不会发生部分重新加载。

请求
GET: http://example.com/events
Accept: text/html, application/xhtml+xml
X-Requested-With: XMLHttpRequest
X-Inertia: true
X-Inertia-Version: 6b16b94d7c51cbe5b1fa42aac98241d5
X-Inertia-Partial-Data: events
X-Inertia-Partial-Component: Events
响应
HTTP/1.1 200 OK
Content-Type: application/json
{
  "component": "Events",
  "props": {
    "auth": {...},       // NOT included
    "categories": [...], // NOT included
    "events": [...]      // included
  },
  "url": "/events/80",
  "version": "c32b8e4965f418ad16eaebba1d4e960f"
}