提供一份 HTML 文件,並設定 Content-Type: text/html; charset=utf-8,在文件 head 中加入標題與描述,並在 body 中放入可閱讀的內容。本 Mac 操作指南會建立一個合成頁面,並確認單一回應包含這三者。
此任務是準備一份可由瀏覽器讀取的公開文件,先使用本機預覽,再將相同結構移轉到發布系統。範例只包含關於紙張形狀的虛構文字,不需要外部素材。
單一類型的 HTTP 回應中應包含什麼?
「類型」指的是回應宣告了媒體類型。Content-Type 欄位會告知接收方表示內容的格式及預期處理方式。此處的格式是 HTML。它不會提供逐欄位的應用程式結構描述。RFC 9110,第 8.3 節
HTTP/1.1 回應包含狀態行、標頭欄位、一個空白行,以及可選的本文。因此,你可以在標頭中傳送傳輸中繼資料,並在本文中放入完整文件,無須另外發出中繼資料請求。RFC 9112,第 2.1 節
這項發布任務可依照以下配置指南。它區分描述 HTTP 表示內容的資訊與描述頁面的資訊。
| 資訊 | 位置 | 範例 |
|---|---|---|
| 表示內容的格式與編碼 | HTTP 標頭 | Content-Type: text/html; charset=utf-8 |
| 文件標題 | HTML head | <title>Paper Shapes: Circle and Square</title> |
| 頁面摘要 | HTML head | <meta name="description" content="A short guide to arranging paper circles and squares."> |
| 面向讀者的內容 | HTML body | 標題、引言與排列說明 |
WHATWG 將 title 元素定義為文件的標題或名稱,並將 description 中繼資料值定義為頁面的描述。使用一個 title,並且最多只使用一個 description 宣告。由於它們位於 HTML 文件內,內容與描述性中繼資料會一起傳送。HTML 標準:文件中繼資料
如何在 Mac 上建立可運作的預覽?
開啟 Terminal,並確認可用的命令:
python3 --version
curl --version
以下程式需要 Python 3.7 或更新版本,且只使用其標準函式庫。如果無法使用 python3,請依照官方 macOS 安裝說明操作,然後重新開啟 Terminal。Python 文件說明了安裝程式,以及如何從終端機執行 python3。在 macOS 上使用 Python
將以下完整區塊貼到 Terminal,包括開頭的命令和最後一行 PY。這會直接執行程式,不會建立或覆寫檔案。檢查頁面時,請讓這個終端機視窗保持執行。
python3 - <<'PY'
from html import escape
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
TITLE = "Paper Shapes: Circle and Square"
SUMMARY = "A short guide to arranging paper circles and squares."
PAGE = f"""<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>{escape(TITLE)}</title>
<meta name="description" content="{escape(SUMMARY, quote=True)}">
</head>
<body>
<main>
<h1>{escape(TITLE)}</h1>
<p>{escape(SUMMARY)}</p>
<h2>Try a simple arrangement</h2>
<p>Place one paper circle beside one paper square.</p>
<p>Switch their positions — then compare the two arrangements.</p>
</main>
</body>
</html>
""".encode("utf-8")
class Handler(BaseHTTPRequestHandler):
protocol_version = "HTTP/1.1"
def respond(self, include_body):
if self.path != "/paper-shapes":
self.send_error(404, "Page not found")
return
self.send_response(200)
self.send_header("Content-Type", "text/html; charset=utf-8")
self.send_header("Content-Length", str(len(PAGE)))
self.end_headers()
if include_body:
self.wfile.write(PAGE)
def do_GET(self):
self.respond(True)
def do_HEAD(self):
self.respond(False)
if __name__ == "__main__":
with ThreadingHTTPServer(("127.0.0.1", 8000), Handler) as server:
print("Preview: http://127.0.0.1:8000/paper-shapes", flush=True)
try:
server.serve_forever()
except KeyboardInterrupt:
pass
PY
此處理常式使用 Python 文件所述的回應方法:send_response() 會開始回應,send_header() 會加入欄位,而 end_headers() 會在寫入本文位元組前結束標頭區段。Python HTTP 伺服器文件
此範例刻意只定義一次 TITLE 和 SUMMARY。這些值同時提供中繼資料與可見文字,讓這份小型文件更容易一致地修改。對於較長的頁面,描述可以與開場段落不同,但仍須準確概述相同主題。
頁面會先編碼,再計算長度。HTTP 將 Content-Length 定義為八位元組,也就是位元組;若計算字元數,這個範例中的破折號就會導致結果錯誤。RFC 9110,第 8.6 節
如何確認內容與中繼資料一併送達?
開啟第二個 Terminal 視窗並執行此命令。它會發出一般文件請求,並顯示回應標頭與內容:
curl -i --max-time 10 http://127.0.0.1:8000/paper-shapes
-i 選項會讓回應標頭與本文一同顯示在輸出串流中。時間限制會將傳輸時間限制在十秒內。這些選項記載於 curl 命令列手冊。
依序檢查輸出:
- 狀態行應顯示
200 OK。 - 單一
Content-Type欄位應宣告text/html; charset=utf-8。 - 標頭區段的空白行之後,HTML 應包含標題與描述。
- 同一份本文應包含紙張形狀的說明。
- 破折號應在解碼後的文字中正確顯示。
接著,在 Safari 的網址列輸入 http://127.0.0.1:8000/paper-shapes。可見頁面應顯示標題、摘要與說明。描述宣告屬於中繼資料;應在傳回的標記中檢查它是否存在,而不是從頁面外觀推斷。
你也可以檢查僅傳回標頭的路徑:
curl -I --max-time 10 http://127.0.0.1:8000/paper-shapes
這會傳送 HEAD,因此無法確認本文是否包含標題或描述。HEAD 回應會省略內容,但會描述對應的表示內容;請使用前面的 GET 檢查來查看實際文件。RFC 9110,第 8.2 節
如果預覽無法正常運作,請根據症狀採取下一步:
| 症狀 | 下一步 |
|---|---|
| 啟動時顯示位址已在使用中 | 在程式中將 8000 改為 8001,重新執行程式,並在每個預覽命令中使用 8001。 |
| 請求顯示連線失敗 | 確認第一個終端機仍顯示預覽正在執行,且連接埠相符。 |
回應為 404 |
請使用 /paper-shapes,不要多加其他內容;此範例不接受結尾斜線或查詢字串。 |
| 瀏覽器仍顯示舊版本 | 按下 Control-C 停止程式,重新執行已編輯的區塊,然後重新載入頁面。 |
| 標題正確,但缺少中繼資料 | 檢查 GET 輸出,並確認宣告位於文件 head 內。 |
Google 搜尋可以從這個回應中使用哪些內容?
描述明確的標題、準確的描述,以及實用的可見文字,都是 Google 用來呈現頁面的已知輸入來源。Google 列出的自動產生標題連結輸入來源包括 title 元素、主要可見標題、標題元素和其他來源。請確保這些資訊都與文件主題一致。調整搜尋結果中的標題連結
Google 主要根據頁面內容產生摘要,有時會在 meta description 更準確描述頁面時採用它。不同搜尋可能會產生不同摘要。請將描述視為實用摘要,而非固定的搜尋結果說明文字。控制搜尋結果中的摘要
在這個合成範例中,描述承諾提供簡短的排列指南,而本文也確實提供該指南。替換範例文字時,請明確確認兩者關係:只閱讀描述的人,應能對頁面內容形成準確的預期。
加入自訂的中繼資料名稱,並不代表 Google 支援這些名稱。Google 表示,它會忽略不支援的 meta 標籤。搜尋用途的中繼資料應使用 Google 文件記載的欄位;若是為自己的應用程式發明的欄位,則需要另外定義使用它的程式。Google 支援的中繼標籤與屬性
如何將預覽轉化為公開發布模式?
本操作指南中的本機網址是桌面預覽,不是已發布的頁面。Python 也說明,http.server 不建議用於正式環境。請將 HTML 結構與回應需求移轉到你的發布系統,不要將此示範當作公開託管服務。Python HTTP 伺服器文件
如果你使用內容管理系統,請查看其中記載的頁面標題與 meta description 設定。Google 指出,CMS 可能提供搜尋設定,而不是直接編輯 HTML。請將這些設定對應到此處示範的欄位,再檢查產生的文件回應。Google 關於新增 meta description 的指南
HTTP 確實支援多部分表示內容,但那是另一種封裝方式。對於這項可由瀏覽器讀取的文件任務,現有的 HTML 結構已能在同一份表示內容中容納內容與文件中繼資料。選用多部分格式會帶來消費端處理需求,而本操作指南並不需要這項需求。RFC 9110,第 8.3.3 節
完成條件很明確:一次成功的文件請求會傳回正確的媒體類型、完整的 HTML 本文、準確的標題與描述,以及讀者前來閱讀的文字。請將這項檢查同時套用於最終公開回應與本機預覽,確保發布系統的輸出符合你準備好的文件。
來源
- RFC 9110:HTTP 語意 — IETF / RFC 編輯部。
- RFC 9112:HTTP/1.1 — IETF / RFC 編輯部。
- HTML 標準:文件中繼資料 — WHATWG。
- 在 macOS 上使用 Python — Python 軟體基金會。
- http.server — HTTP 伺服器 — Python 軟體基金會。
- curl — 使用方式 — curl。
- 影響 Google 搜尋中的標題連結 — Google 搜尋中心。
- 如何撰寫 Meta Description — Google 搜尋中心。
- Google 支援的中繼標籤與屬性 — Google 搜尋中心。