域名教程實(shí)戰(zhàn):Capstone 網(wǎng)站本地構(gòu)建與全鏈路測(cè)試指南)
US.KG 免費(fèi)域名教程實(shí)戰(zhàn):Capstone 網(wǎng)站本地構(gòu)建與全鏈路測(cè)試指南【免費(fèi)下載鏈接】US.KGFree domain registration and practical DNS learning resources for everyone.項(xiàng)目地址: https://gitcode.com/GitHub_Trending/us/US.KG本文基于 US.KG(DigitalPlat FreeDomain)教程第七部分 Capstone 項(xiàng)目的第二課,完整講解如何在動(dòng)手修改公網(wǎng) DNS 和服務(wù)器之前,在本地把最終要上線的靜態(tài)網(wǎng)站完整構(gòu)建并測(cè)試一遍。讀完后你將能夠獨(dú)立搭建一個(gè)含首頁、About 頁與樣式表的兩頁站點(diǎn),用本地 HTTP 服務(wù)器跑通功能測(cè)試、可訪問性測(cè)試與內(nèi)容隱私審查,并以可復(fù)現(xiàn)的版本基線作為進(jìn)入注冊(cè)/部署階段的放行門檻。一、為什么必須先本地,后公網(wǎng)Capstone 項(xiàng)目把整本書的內(nèi)容收斂為一個(gè)完整工程:規(guī)劃、注冊(cè)、構(gòu)建、部署、加固、驗(yàn)收、運(yùn)維(見 Part 7 索引)。本課 Build and Test the Site 處在流程的關(guān)鍵位置:上一步 Project Brief and Architecture 已經(jīng)確定了頁面范圍、域名命名與架構(gòu)分工,而下一步 Register, Deploy, and Connect 會(huì)真正創(chuàng)建外部狀態(tài)——注冊(cè)域名、修改 nameserver、在公網(wǎng)服務(wù)器上安裝 Nginx。因此原文檔開篇就立下一條紀(jì)律:Build the complete website locally before making a public DNS or server change.在做任何公網(wǎng) DNS 或服務(wù)器變更之前,先在本地把完整網(wǎng)站構(gòu)建出來。這條紀(jì)律的回報(bào)是:所有低級(jí)錯(cuò)誤(文件缺失、鏈接失效、樣式未加載、隱私信息誤發(fā)布)都在不產(chǎn)生外部副作用的本地環(huán)境被攔截。原文明確設(shè)置了放行閘門(Gate):Do not continue until all local tests pass and the source can rebuild the site on another machine.在所有本地測(cè)試通過、且源碼可以在另一臺(tái)機(jī)器上重建出該網(wǎng)站之前,不要繼續(xù)。對(duì)照 7.1 項(xiàng)目簡(jiǎn)報(bào)中的架構(gòu)圖,本地構(gòu)建出的三個(gè)文件index.html、about.html、styles.css正是未來要部署到服務(wù)器上/var/www/example.dpdns.org目錄的內(nèi)容——本地目錄結(jié)構(gòu)與生產(chǎn)目錄結(jié)構(gòu)一一對(duì)應(yīng),是本課可執(zhí)行性的基礎(chǔ)。二、Step 1:創(chuàng)建項(xiàng)目骨架與版本控制2.1 創(chuàng)建目錄結(jié)構(gòu)mkdir -p capstone-site/assets capstone-site/notes cd capstone-site目錄劃分與 7.1 項(xiàng)目簡(jiǎn)報(bào)的規(guī)劃相互呼應(yīng):notes/用于存放 ownership(責(zé)任人分工)與 acceptance(驗(yàn)收證據(jù))等項(xiàng)目筆記,assets/預(yù)留給靜態(tài)資源。2.2 創(chuàng)建 .gitignore.DS_Store .env *.log notes/private-*每一項(xiàng)都對(duì)應(yīng)一種真實(shí)的泄漏風(fēng)險(xiǎn):.DS_Store:macOS 目錄元數(shù)據(jù),避免把本機(jī)目錄結(jié)構(gòu)噪音提交進(jìn)倉庫;.env:環(huán)境變量文件,通常承載密鑰,絕不能進(jìn)入版本庫;*.log:日志文件,既含隱私也易產(chǎn)生無意義 diff;notes/private-*:項(xiàng)目筆記中的私密草稿(如賬號(hào)恢復(fù)信息),與 7.1 中定義的私有數(shù)據(jù)清單(賬號(hào)密碼、恢復(fù)碼、API 密鑰、SSH 私鑰等)保持邊界一致。2.3 初始化版本控制git init git status先執(zhí)行g(shù)it status觀察未跟蹤文件,確認(rèn)目錄內(nèi)容符合預(yù)期后再進(jìn)入后續(xù)步驟。版本控制在這里的作用不是團(tuán)隊(duì)協(xié)作,而是讓源碼可以在另一臺(tái)機(jī)器上重建站點(diǎn)這一閘門要求可驗(yàn)證、可回滾。三、Step 2:創(chuàng)建首頁 index.html完整代碼如下,注意其中每個(gè)可訪問性細(xì)節(jié)都在第 8 節(jié)的測(cè)試清單中被逐一驗(yàn)證:!doctype html html langen head meta charsetutf-8 meta nameviewport contentwidthdevice-width, initial-scale1 meta namedescription contentA short description of the project and its purpose. titleExample Project/title link relstylesheet hrefstyles.css /head body a classskip-link href#contentSkip to content/a header classsite-header nav classnav aria-labelPrimary navigation a classbrand hrefindex.htmlExample Project/a a hrefabout.htmlAbout/a /nav /header main idcontent classpage p classeyebrowOpen and useful/p h1A clear statement of what the project does./h1 p classledeExplain who the project serves and why it exists in two short sentences./p a classbutton hrefabout.htmlLearn about the project/a /main footer classsite-footer pContact: a hrefmailto:contactexample.dpdns.orgcontactexample.dpdns.org/a/p /footer /body /html值得逐條理解的關(guān)鍵點(diǎn):langen與meta description:每個(gè)公開頁面都需要唯一的title與有意義的 description,這是 可訪問性與搜索基礎(chǔ)中Page Metadata一節(jié)的直接落地——它幫助用戶區(qū)分標(biāo)簽頁,并幫助搜索系統(tǒng)理解頁面,但并不保證排名;skip-link:a classskip-link href#contentSkip to content/a位于body第一個(gè)交互元素的位置,讓鍵盤用戶跳過導(dǎo)航直達(dá)正文。它平時(shí)被 CSS 隱藏(見第 5 節(jié)),獲得焦點(diǎn)時(shí)才顯現(xiàn);語義化標(biāo)簽:nav aria-labelPrimary navigation、main idcontent使用原生元素而非通用div拼湊,天然攜帶鍵盤行為與語義,這正是 3.8 章節(jié)Start with Semantic HTML原則的體現(xiàn);虛擬聯(lián)系郵箱:原文特別強(qiáng)調(diào),contactexample.dpdns.org是虛構(gòu)的占位值,只有當(dāng)存在一個(gè)被監(jiān)控的郵箱且你有意公開發(fā)布時(shí),才應(yīng)替換為真實(shí)地址。這與 7.1 中Public vs Private 數(shù)據(jù)的劃分一致:聯(lián)系方式屬于可公開數(shù)據(jù),但必須是你實(shí)際能收信、愿公開的地址。四、Step 3:創(chuàng)建 About 頁 about.html!doctype html html langen head meta charsetutf-8 meta nameviewport contentwidthdevice-width, initial-scale1 meta namedescription contentBackground, purpose, and contact information for Example Project. titleAbout | Example Project/title link relstylesheet hrefstyles.css /head body a classskip-link href#contentSkip to content/a header classsite-header nav classnav aria-labelPrimary navigation a classbrand hrefindex.htmlExample Project/a a aria-currentpage hrefabout.htmlAbout/a /nav /header main idcontent classpage prose h1About the project/h1 pDescribe the problem that led to the project./p h2What we provide/h2 pDescribe the useful information or service available here./p h2Contact/h2 pExplain how a visitor can reach the responsible team./p /main footer classsite-footer pa hrefindex.htmlReturn home/a/p /footer /body /html與首頁相比,這頁有兩處刻意的差異:當(dāng)前頁導(dǎo)航項(xiàng)使用aria-currentpage標(biāo)記,向輔助技術(shù)聲明這就是你所在的頁面;main增加prose類、正文使用h1之下嵌套h2的嚴(yán)格標(biāo)題層級(jí)——第 8 節(jié)確認(rèn)標(biāo)題順序測(cè)試直接針對(duì)這一點(diǎn)。標(biāo)題層級(jí)、描述性鏈接文案(About、Return home、Learn about the project 均描述了去向)都對(duì)應(yīng) 3.8 章節(jié)中結(jié)構(gòu)化內(nèi)容同時(shí)利于可訪問性與搜索理解的要求。五、Step 4:創(chuàng)建樣式表 styles.css*, *::before, *::after { box-sizing: border-box; } :root { color-scheme: light; font-family: system-ui, sans-serif; line-height: 1.6; background: #f8fafc; color: #0f172a; } body { min-height: 100vh; margin: 0; } a { color: #075985; } a:focus-visible { outline: 3px solid #0ea5e9; outline-offset: 3px; } .skip-link { position: absolute; left: 1rem; top: -5rem; padding: 0.75rem 1rem; background: #ffffff; } .skip-link:focus { top: 1rem; } .site-header, .site-footer { border-block: 1px solid #cbd5e1; background: #ffffff; } .nav, .page, .site-footer p { width: min(68rem, calc(100% - 2rem)); margin-inline: auto; } .nav { display: flex; align-items: center; justify-content: space-between; min-height: 4rem; } .brand { font-weight: 750; text-decoration: none; } .page { padding-block: clamp(4rem, 10vw, 8rem); } .page h1 { max-width: 18ch; font-size: clamp(2.25rem, 6vw, 4.75rem); line-height: 1.05; } .eyebrow { color: #0369a1; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase; } .lede, .prose { max-width: 44rem; } .button { display: inline-block; margin-top: 1rem; padding: 0.8rem 1rem; border-radius: 0.5rem; background: #075985; color: #ffffff; font-weight: 700; text-decoration: none; } .site-footer { padding-block: 1rem; } media (prefers-reduced-motion: no-preference) { a { transition: color 150ms ease, background-color 150ms ease; } }這段樣式表雖然不長(zhǎng),但每個(gè)區(qū)塊都有明確的工程意圖,值得結(jié)合源碼逐塊解讀:區(qū)塊關(guān)鍵聲明作用與依據(jù)全局盒模型box-sizing: border-box讓所有元素(含偽元素)的 padding/border 計(jì)入寬度,是響應(yīng)式布局可預(yù)測(cè)的前提:root主題變量color-scheme: light、system-ui、line-height: 1.6聲明淺色方案避免瀏覽器自動(dòng)深色化造成對(duì)比度失控;系統(tǒng)字體棧零加載成本;1.6 行高保障長(zhǎng)文可讀性焦點(diǎn)樣式a:focus-visible { outline: 3px solid #0ea5e9; outline-offset: 3px }用:focus-visible而非簡(jiǎn)單outline: none思路,保證鍵盤導(dǎo)航時(shí)焦點(diǎn)永遠(yuǎn)可見——對(duì)應(yīng) 3.8 章節(jié)不要移除焦點(diǎn)輪廓而不提供清晰替代的硬性要求Skip link 機(jī)制.skip-link { top: -5rem }.skip-link:focus { top: 1rem }平時(shí)移出視口上方(位置絕對(duì),不占布局),獲得焦點(diǎn)時(shí)下移 1rem 可見——首頁中Skip to content鏈接的顯示邏輯完全由這兩條規(guī)則驅(qū)動(dòng)響應(yīng)式寬度width: min(68rem, calc(100% - 2rem))margin-inline: auto大屏上限 68rem、小屏兩側(cè)各留 1rem,無需媒體查詢即可實(shí)現(xiàn)居中容器流式排版padding-block: clamp(4rem, 10vw, 8rem)、font-size: clamp(2.25rem, 6vw, 4.75rem)clamp()在最小/最大約束間隨視口插值,第 8 節(jié)200% 縮放與窄視口測(cè)試即驗(yàn)證這種流式行為正文字寬.lede, .prose { max-width: 44rem }限制行長(zhǎng)約 44rem,符合可讀行寬慣例動(dòng)效降級(jí)media (prefers-reduced-motion: no-preference)鏈接過渡動(dòng)畫僅在用戶未開啟減少動(dòng)態(tài)效果時(shí)啟用,尊重系統(tǒng)偏好注意:root聲明color-scheme: light,意味著該站點(diǎn)以淺色為既定主題;3.3 本地測(cè)試章節(jié)要求文本在淺色與深色系統(tǒng)主題下均可讀,該聲明正是讓頁面在深色系統(tǒng)主題下也不會(huì)出現(xiàn)深色文字配深色背景錯(cuò)亂的保證。六、Step 5:啟動(dòng)本地服務(wù)器python3 -m http.server 8000 --bind 127.0.0.1然后打開http://127.0.0.1:8000/。這里有兩個(gè)關(guān)鍵細(xì)節(jié):為什么不直接雙擊打開index.html?直接用file://協(xié)議打開文件無法復(fù)現(xiàn)真實(shí) Web 服務(wù)器行為(相對(duì)路徑解析、MIME 類型、404 語義都不同),3.3 章節(jié)開宗明義:Openingindex.htmldirectly does not reproduce all web-server behavior. Run a local HTTP server instead.--bind 127.0.0.1的意義:把開發(fā)服務(wù)器限制在本地回環(huán)接口。3.3 章節(jié)警告,綁定到0.0.0.0會(huì)讓服務(wù)器在防火墻允許的每一個(gè)網(wǎng)絡(luò)接口上可達(dá),只有當(dāng)你刻意要做局域網(wǎng)測(cè)試且文件確實(shí)可以分享時(shí)才該這樣做。測(cè)試完畢后按CtrlC停止服務(wù)器,并可用lsof -nP -iTCP:8000 -sTCP:LISTEN確認(rèn)沒有進(jìn)程殘留監(jiān)聽該端口(無輸出即已停止)。這個(gè)開發(fā)服務(wù)器只用于本地測(cè)試,不用于公網(wǎng)生產(chǎn)——生產(chǎn)環(huán)境由 7.3 章節(jié)中的 Nginx 承擔(dān)。七、Step 6:功能測(cè)試在另一個(gè)終端中,對(duì)三個(gè)資源逐一發(fā)起 HEAD 請(qǐng)求:curl -I http://127.0.0.1:8000/ curl -I http://127.0.0.1:8000/about.html curl -I http://127.0.0.1:8000/styles.css預(yù)期結(jié)果(原文逐條列出):兩個(gè)頁面都返回200;樣式表返回200且攜帶 CSS 的 Content-Type;首頁鏈接到 About 頁;About 頁鏈接回首頁。結(jié)合 Python 標(biāo)準(zhǔn)庫的實(shí)現(xiàn)可以推斷:python3 -m http.server的SimpleHTTPRequestHandler會(huì)通過mimetypes模塊解析擴(kuò)展名,因此.html應(yīng)返回Content-Type: text/html、.css應(yīng)返回Content-Type: text/css(隨系統(tǒng) MIME 數(shù)據(jù)庫可能帶 charset 參數(shù))。如果styles.css返回的不是 CSS 類型,瀏覽器可能拒絕應(yīng)用樣式,這類問題必須在此階段發(fā)現(xiàn),而不是上線后排查。功能測(cè)試不只是狀態(tài)碼:兩條鏈接互指的斷言驗(yàn)證的是 7.1 架構(gòu)中Home 與 About 相互可達(dá)這一頁面結(jié)構(gòu)契約,對(duì)應(yīng) 7.1 驗(yàn)收清單里Home and About links work一條。八、Step 7:可訪問性測(cè)試原文給出七項(xiàng)手動(dòng)測(cè)試清單,它們與樣式表、HTML 結(jié)構(gòu)形成一一對(duì)應(yīng)的驗(yàn)證鏈:測(cè)試項(xiàng)被驗(yàn)證的實(shí)現(xiàn)用Tab與Enter完成全部導(dǎo)航原生a元素天然可聚焦、可激活(3.8 章節(jié)鍵盤導(dǎo)航1–5 步的現(xiàn)場(chǎng)執(zhí)行)確認(rèn) skip link 在獲得焦點(diǎn)時(shí)出現(xiàn).skip-link:focus { top: 1rem }規(guī)則(第 5 節(jié))確認(rèn)焦點(diǎn)始終可見a:focus-visible的 3px 輪廓規(guī)則(第 5 節(jié))放大到 200%clamp()流式字號(hào)與min(68rem, ...)容器寬度在縮放后不產(chǎn)生橫向滾動(dòng)或溢出測(cè)試窄視口同上,驗(yàn)證calc(100% - 2rem)在小屏下的表現(xiàn)確認(rèn)標(biāo)題順序About 頁h1→h2的層級(jí)(第 4 節(jié))確認(rèn)每個(gè)鏈接都描述其去向About、Return home、Learn about the project 等文案這套清單與 3.8 章節(jié)Accessibility Review Lab的七步審查法同源(鍵盤導(dǎo)航、替代文本、標(biāo)題順序、200% 縮放、窄視口、禁用 CSS 后文檔仍可讀、記錄并修復(fù)至少三個(gè)問題),本課將其裁剪為與兩頁站點(diǎn)直接相關(guān)的可執(zhí)行子集。九、Step 8:內(nèi)容與隱私審查在提交任何公開內(nèi)容之前,用 ripgrep 掃描整個(gè)項(xiàng)目:rg -n -i password|token|secret|api[_-]?key|192\.168\. .正則各分量的含義:-n -i:輸出行號(hào)、忽略大小寫;password|token|secret:憑據(jù)類關(guān)鍵字;api[_-]?key:同時(shí)覆蓋apikey、api_key、api-key三種命名習(xí)慣;192\.168\.:轉(zhuǎn)義的.精確匹配內(nèi)網(wǎng)地址段前綴,防止把本機(jī)內(nèi)網(wǎng) IP 寫進(jìn)公開頁面(這正是 3.3 章節(jié)HTML 或 CSS 中不應(yīng)出現(xiàn)本地絕對(duì)路徑/本地地址檢查的終端版)。對(duì)每一條命中都必須人工復(fù)核。原文隨后給出兩條判定標(biāo)準(zhǔn):公開的聯(lián)系信息必須是有意為之;站點(diǎn)目錄內(nèi)不得殘留私密筆記——對(duì)應(yīng).gitignore中notes/private-*規(guī)則:私密筆記應(yīng)放在被忽略的模式內(nèi),且根本不應(yīng)出現(xiàn)在capstone-site的公開文件中。十、Step 9:保存版本基線git add index.html about.html styles.css .gitignore git diff --cached git commit -m Create capstone static site注意原文的操作順序紀(jì)律:Only commit after reviewing the staged content.——先git diff --cached審查暫存區(qū)內(nèi)容,確認(rèn)沒有意外文件(如誤放的notes/private-*草稿)之后,再執(zhí)行 commit。這個(gè)基線提交的價(jià)值在于:它是源碼可在另一臺(tái)機(jī)器上重建站點(diǎn)這一閘門要求的直接證據(jù):git clone 三個(gè)源文件即可完整復(fù)現(xiàn);后續(xù) 7.3 部署與 7.4 運(yùn)維階段若需要回滾,該 commit 就是已知良好的恢復(fù)點(diǎn),與 7.1 中回滾計(jì)劃Website backup location / Command to restore files兩個(gè)字段直接銜接。十一、放行閘門:何時(shí)可以進(jìn)入公網(wǎng)階段本課結(jié)束時(shí),原文設(shè)置了一道硬閘門:Do not continue until all local tests pass and the source can rebuild the site on another machine.即必須同時(shí)滿足:第六節(jié)三個(gè)curl -I全部符合預(yù)期(兩個(gè)頁面 200、樣式表 200 且為 CSS 類型、雙向鏈接成立);第七節(jié)七項(xiàng)可訪問性檢查全部通過;第九節(jié)隱私掃描無未處理命中;第十節(jié)基線 commit 完成,且該源碼在另一臺(tái)機(jī)器上能重建出站點(diǎn)。滿足以上條件后,才進(jìn)入下一章 Register, Deploy, and Connect——準(zhǔn)備 DNS zone、注冊(cè)域名、驗(yàn)證委派、安裝 Nginx 并把本地產(chǎn)物部署到/var/www/example.dpdns.org。本地測(cè)試做得越徹底,公網(wǎng)階段要面對(duì)的未知數(shù)就越少,這正是整個(gè) Capstone 先本地、后公網(wǎng)方法論的核心?!久赓M(fèi)下載鏈接】US.KGFree domain registration and practical DNS learning resources for everyone.項(xiàng)目地址: https://gitcode.com/GitHub_Trending/us/US.KG創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考