Inertia.js 不是框架,也不是要來取代現有的框架。Inertia.js 的本質是個前端的路由套件,透過銜接既有的「前端框架」和「後端框架」,來達到用「後端框架」建立 Web 應用,卻可以輕鬆使用「前端框架」建構整個前端的部分 (不用 REST 或 GraphQL API 了,放置在一旁...)。Inertia 可以不用 GraphQL 卻擁有 GraphQL 的優勢,前端還有本地資料緩存、滾動記憶、pushState
等功能。
那前後端中間勢必要有溝通的規則,沒錯,那就是接下來要來介紹的——Inertia 協議。
看到這裡你會發現,現在有 Inertia.js 和 Inertia 兩種名稱,我個人的簡單區分的方式:Inertia 是這套嶄新的網頁架構,其中包含協議和需要遵守的規則;Inertia.js 是實現其功能的前端套件。但官方文檔中對兩個名稱的的界線似乎也很模糊。大概了解不同之處就可以了。
還記得原本網頁最基本的 HTTP 請求(Request)/響應(Response) 是如何運作的?
如果是後端應用,基本上都是發正常的 HTTP 請求,然後回一個 HTML 的響應。而前端應用除了第一次請求當作進入點的 HTML 後,其他次都是發 XHR (XMLHttpRequest) 請求打 API,並回一個 JSON 格式的響應。
然後你會發現在同一個應用中,兩種請求方式是不能共用路由的。不過那混合版的 Inertia 則會「見人說人話,見○說○話」。
Inertia 定義一個路由,可以同時收 HTTP 請求,也可以收 XHR 請求。但這個 XHR 請求有特殊規則 (等下會解釋),我們先管叫它 Inertia 請求。
如果是第一次、也就是正常的 HTTP 請求,就回傳 SPA 進入點的 HTML (別忘了 Inertia 的前端部分是 SPA 模式),並加載需要的 CSS、JS、Fonts 等資源。還會把當前頁面的 Inertia Page 物件 (目標頁面的資料) 塞進根元素的 data-page
屬性,交由前端渲染該頁面:
這些 HTTP 範例是參考(
複製)自 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's 36th birthday party!"}},"url":"/events/80","version":"c32b8e4965f418ad16eaebba1d4e960f"}'></div>
</body>
</html>
然後要瀏覽其他頁面時,點擊頁面中的 <inertia-link>
組件,會送出 Inertia 請求 取得 Inertia Page 物件,Inertia 就可以不刷新頁面,自動替換出新的頁面內容,達到 SPA 般舒適的瀏覽體驗。
要如何發送「正規」的 Inertia 請求 呢?首先必須要將 X-Inertia
Header 設為 true
,其次是必須回傳 Inertia Page 物件,這就是 Inertia 的規則。
同時也可以設定其他
X-Inertia
開頭的 Header,例如像下面的X-Inertia-Version
和X-Inertia-Partial-Data
等,在後面的篇章會介紹到。
請求:
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
{
"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 Page 物件,其實就是上面的那個 JSON 物件。顧名思義,Inertia Page 物件 裝的就是頁面的資料。在 Inertia 的規則中,必須要有以下屬性:
Inertia Page 物件 也就是可以用兩種發送請求並渲染頁面的關鍵,在 Inertia 中扮演著非常重要的角色。
有了這些規則後,我們就可以在我們的前端框架和後端框架實作出來,但如果每次都要實作才能開發專案...也太累了吧。因此 Inertia 官方提供了數套適用前端框架和後端框架的套件:
ㄝ...那個 Inertia.js 怎麼消失了呢?其實它還在。前端的 Inertia 套件都是包裝過 Inertia.js 並針對各個框架適配。
只要一個前端和一個後端,隨你怎麼搭,都可以建構 Inertia 架構的 SPA 應用!如果你想要用其他框架,可以參考社區維護的 Inertia 套件。
到此講完了基本的 Inertia.js 的架構、概念了,如果還是不懂沒關係,之後實作完之後再回來看本篇會更清楚。下一篇開始正式進入開發網站了,請先準備好可以運行 Laravel 的環境吧!如果有開發過 Laravel 應用應該都知道,需要準備 PHP、Composer、Git、Node.js(NPM) 等必備的套件。還有,因為有個套件的限制,PHP 要使用 7.4 版,要注意一下。