National Taiwan University
Uedu Main Site
Explore Uedu
Student Console
Register as Member/Login
Research Informed Consent Center
Survey Center
Educational Big Data Challenge
Claim or create a course
Try a Scenario Task
Support & Messages
Uptime Data

UeduGPTs

--

Jupyters

2

Local AI

--

Uedu Code

--

台灣大學 AQI 70 24°C PM2.5 17
AI Reply Desktop Notifications

Show a desktop notification when the AI TA finishes replying

Chat Message Notifications

Notify me when classmates post messages in the forum

Sound notification

Play an alert sound whenever there is a new notification

Unit 23

網頁測試伺服器

為什麼需要本機伺服器、http-server 與 query string
Interaction實作導覽 15 minute(s)

Learning Objectives

  • 說明用 file:// 直接開網頁會遇到哪些限制,以及為什麼開發時要用本機伺服器
  • 用 Node.js 的 npx http-server、Python 的 http.server 或 VS Code Live Server 開啟本機伺服器
  • 說明 localhost、127.0.0.1 與連接埠(port)的意思,並看懂一個網址的各個部分
  • 說明 query string 的組成,用 URL 與 URLSearchParams 讀取與組出 query string

為什麼要開一個本機伺服器

在檔案總管裡對 index.html 按兩下,瀏覽器的網址列會出現 file:///C:/Users/…/index.html: 瀏覽器是直接讀取硬碟上的檔案,中間沒有伺服器。只放 HTML、CSS 和簡單的 JavaScript 時這樣沒問題, 但接下來幾課的功能,用 file:// 開就會出問題:

想做的事 用 file:// 開啟時
用 fetch 讀取同一個資料夾裡的 data.json(AJAX 那一課) Chrome、Edge 會拒絕,主控台出現錯誤;各瀏覽器的規則不完全相同
用 <script type="module"> 載入 ES 模組(模組那一課) 會出現 CORS 錯誤,模組載入失敗
測試網址後面帶的 query string、模擬網站真正的運作方式 沒有伺服器,看不到網頁與伺服器之間的請求

原因是瀏覽器的安全規則:從 file:// 開啟的網頁不能隨意讀取你硬碟上的其他檔案,否則任何一個下載回來的 HTML 都可能偷看你的資料。

解決方法是在自己的電腦上啟動一個網頁伺服器(web server),讓瀏覽器用 http:// 向它要檔案, 就和連上真正的網站一樣。這種只在本機開發、測試用的伺服器,常叫做本機伺服器或開發伺服器(dev server)。

Node.js、npm 與 npx

最常用的工具是 Node.js 生態系裡的 http-server,先認識三個名字:

名稱 是什麼
Node.js 讓 JavaScript 在瀏覽器以外執行的環境,以 Google 的 V8 引擎為基礎,常用來寫伺服器端程式與開發工具
npm(Node Package Manager) Node.js 的套件管理工具,安裝 Node.js 時會一起裝好;可以從 npmjs.com 下載別人寫好的套件
npx 也隨 npm 一起安裝,可以「直接執行」一個套件提供的指令;本機沒有這個套件時,會先問你要不要下載

投影片的做法是先用 npm install -g http-server 全域安裝(-g 表示裝在系統上,任何資料夾都能用),再執行 http-server。 現在更常見的做法是用 npx http-server,不必先安裝,也不會在系統上留下全域套件。兩種方式啟動的是同一個伺服器。

Node.js 請到官方網站 nodejs.org 下載標示 LTS(長期支援)的版本;2026 年 10 月查詢時最新的 LTS 是 v26。

用 npx http-server 啟動本機伺服器

安裝 Node.js 之後,打開終端機(Windows 可用「命令提示字元」、PowerShell 或 VS Code 的終端機),跟著下面幾步做。

  1. 1

    確認 Node.js 已經安裝

    node -v(或 node --version)會顯示版本號碼;輸入 npm -v 可以看到隨附的 npm 版本。看到「不是內部或外部命令」之類的訊息,表示還沒安裝,或是安裝後沒有重新開啟終端機。

  2. 2

    進入網頁所在的資料夾

    伺服器會把「目前所在的資料夾」當成網站的根目錄。先建立一個資料夾,用 VS Code 在裡面新增 index.html,再用 cd 進入這個資料夾。

  3. 3

    用 npx 啟動 http-server

    -p 8000 指定連接埠為 8000(沒有指定時預設是 8080)。第一次執行時 npx 會問要不要下載 http-server,輸入 y 再按 Enter。看到 Available on 就表示伺服器啟動了,下面列的網址就是瀏覽器要開的位址。版本不同時,設定的列表會略有差異。

  4. 4

    在瀏覽器開啟網頁

    打開瀏覽器,輸入 http://127.0.0.1:8000(或 http://localhost:8000),就會看到 index.html。網址列現在是 http:// 開頭,表示網頁是從伺服器送來的。

    幾個常用的選項(npx http-server -h 列出全部):

    選項 作用
    -p 8000 指定連接埠(預設 8080)
    -o 啟動後自動開啟瀏覽器
    -c-1 關閉快取。預設會讓瀏覽器快取 3600 秒,改了檔案卻看到舊畫面時可以加上它
    --cors 允許其他網域的網頁向這個伺服器要資料
    -a 127.0.0.1 只接受本機連線(預設 0.0.0.0:同一個網路裡的其他裝置也能連進來)

    另外,資料夾裡如果有 public 子資料夾,http-server 會改用 public 當網站根目錄。

  5. 5

    停止伺服器

    在終端機按 Ctrl+C 就會停止伺服器,瀏覽器重新整理後就連不上了。開發時通常讓它一直開著,另外開一個終端機做其他事。

這段導覽完成了

其他方式:Python 與 VS Code Live Server

沒有安裝 Node.js 也沒關係,下面兩種方式效果相同,選一種順手的就好。

  1. 1

    Python 內建的 http.server

    電腦裡有 Python 3 的話,一行指令就能啟動;macOS 與 Linux 通常要打 python3。:: 代表接受所有網路介面的連線,瀏覽器一樣開 http://127.0.0.1:8000。每收到一個請求,終端機就會多一行紀錄:請求的路徑(包含 query string)與狀態碼 200。

  2. 2

    只讓自己的電腦連線

    加上 --bind 127.0.0.1,同一個網路裡的其他裝置就連不進來,開發時這樣比較安全。

  3. 3

    VS Code 的 Live Server 擴充功能

    在 VS Code 的擴充功能市集搜尋 Live Server(作者 Ritwick Dey)並安裝。開啟網頁資料夾後,點視窗右下角狀態列的 Go Live,或在 HTML 檔上按右鍵選 Open with Live Server,瀏覽器會自動開啟(網址通常是 http://127.0.0.1:5500)。它的特色是存檔後瀏覽器會自動重新整理;再按一次狀態列的按鈕就會停止。

這段導覽完成了

localhost、連接埠與網址的組成

localhost 是「這台電腦自己」的名字,對應的 IP 位址是 127.0.0.1。瀏覽器連到 localhost,就是連到你自己電腦上的伺服器,資料不會離開你的電腦。

一台電腦可以同時跑好幾個伺服器,靠連接埠(port)區分,像同一棟大樓的不同門牌: http-server 預設 8080、Python 常用 8000、Live Server 常用 5500。兩個程式不能同時使用同一個連接埠, 啟動時看到「address already in use」(連接埠已被使用),就換一個號碼。

一個網址可以拆成好幾個部分:

部分 範例 http://127.0.0.1:8000/test.html?username=amy&lang=zh-TW#top URL 物件的屬性
通訊協定 http: protocol
主機名稱 127.0.0.1 hostname
連接埠 8000 port
路徑 /test.html pathname
query string ?username=amy&lang=zh-TW search
錨點(hash) #top hash

JavaScript 的 URL 物件可以幫你拆:new URL(網址) 之後讀取上面這些屬性。 在網頁裡,目前這一頁的網址是 location.href,所以常寫成 new URL(location.href)。

用 URL 物件拆開網址

逐步播放,對照下方輸出:每一行印出網址的一個部分。注意 search 包含開頭的 ?,hash 包含 #;用 https 預設的連接埠(443)時網址裡不寫連接埠,port 就是空字串。

query string:網址後面帶的資料

網址 ? 後面那一段叫 query string(查詢字串),用來把簡單的資料傳給網頁或伺服器:

  • 從 ? 開始,由好幾組參數組成,參數之間用 & 隔開
  • 每組參數是 key=value,用 = 連接,例如 username=amy&age=20
  • 同一個 key 可以出現好幾次,例如 tag=js&tag=web
  • 中文、空白等特殊字元要經過編碼(URL encoding),例如空白變成 + 或 %20

例如 https://github.com/search?q=querystring&type=Code 的 query string 是 q=querystring&type=Code。 表單用 GET 送出(<form action="result.html"> 預設的方式)時,瀏覽器也會把每個欄位的 name=值 組成 query string 接在網址後面。

讀取 query string 不要自己用 split('&') 切字串,交給 URLSearchParams:它會處理編碼、重複的 key 與找不到的情況。

方法 作用
params.get('age') 取得第一個值(一律是字串);沒有這個 key 時回傳 null
params.getAll('tag') 取得所有同名的值,回傳陣列
params.has('age') 有沒有這個 key
params.set('page', '3')、params.append('tag', 'css') 設定(取代同名的)或新增一組參數
params.toString() 組回 query string(自動編碼)

不要把密碼等敏感資料放在 query string:網址會留在瀏覽器的歷史紀錄與伺服器的紀錄檔,也可能被別人看到或分享出去。

用 URLSearchParams 讀取參數

看右邊變數的值:get 拿到的一律是字串,要計算就先用 Number() 轉換;getAll 回傳陣列;找不到的 key 是 null。最後的 for…of 會依序取出每一組 key 與 value。

反過來:組出 query string

想把資料放進網址時,用 append、set 加入參數,再用 toString() 組成字串。看第 8 行的輸出:中文被編碼成 %E5%8F%B0…,空白變成 +;用 get 讀回來時會自動解碼。

在網頁裡測試送出 query string

把下面的 test.html 放進伺服器的資料夾,在瀏覽器開啟 http://127.0.0.1:8000/test.html?username=amy&age=20, 畫面就會顯示網址裡帶的名字。改掉網址裡的值再按 Enter,畫面跟著變;終端機裡也會看到這一次請求的紀錄。

<!DOCTYPE html>
<html lang="zh-Hant">
<head><meta charset="utf-8"><title>測試 query string</title></head>
<body>
  <p id="msg"></p>
  <script>
    const params = new URL(location.href).searchParams;
    const name = params.get('username') ?? '訪客';
    document.getElementById('msg').textContent = '你好,' + name;
  </script>
</body>
</html>

?? 的意思是「左邊是 null 或 undefined 時改用右邊」:網址沒有帶 username 時顯示「訪客」。 放進頁面時用 textContent 而不是 innerHTML:網址是任何人都能改的,不能讓別人在網址裡塞進 HTML。

想一想:本機伺服器

1.

直接在檔案總管對 index.html 按兩下,用 file:// 開啟。在 Chrome 裡,下列哪一件事最可能失敗?

2.

在終端機執行 npx http-server -p 8000 之後,瀏覽器要開哪一個網址?

3.

關於 localhost 與連接埠,下列哪一個說法正確?

第 1 次作答

想一想:query string

1.

下面的程式會印出什麼?

const url = new URL('https://github.com/search?q=querystring&type=Code');
console.log(url.search);
2.

下面的程式會印出什麼?

const p = new URLSearchParams('a=1&b=2&a=3');
console.log(p.get('a'), p.getAll('a').length);
3.

下面的程式會印出什麼?

const p = new URLSearchParams('name=amy');
console.log(p.get('age'));
4.

下列哪一種資料不應該放在 query string 裡?

第 1 次作答

實作:從網址讀出訂單

網址 http://127.0.0.1:8000/order.html?item=latte&qty=2&size=L 帶了一筆飲料訂單。用 URL 與 searchParams 讀出三個參數,印出 latte x 2(L),再用單價 60 算出總價,印出 總價 120。

你的輸出
預期輸出

重點精華回顧

  • 用 file:// 直接開網頁時,fetch 讀本機檔案、ES 模組等功能會被瀏覽器的安全規則擋下;開發時改用本機伺服器,以 http:// 開啟。
  • Node.js 是瀏覽器以外的 JavaScript 執行環境,npm 是它的套件管理工具;npx http-server -p 8000 不必先安裝就能啟動伺服器,Ctrl+C 停止。
  • 其他選擇:Python 的 python -m http.server 8000、VS Code 的 Live Server(存檔自動重新整理)。
  • localhost(127.0.0.1)是自己的電腦,連接埠用來區分同一台電腦上的不同伺服器。
  • 網址由通訊協定、主機名稱、連接埠、路徑、query string、hash 組成,new URL() 可以拆開它。
  • query string 從 ? 開始,key=value 之間用 & 隔開;用 URLSearchParams 的 get、getAll、has 讀取,get 回傳字串或 null。
  • 密碼等敏感資料不要放在 query string。
這一課完成了!
Next lesson:Promise
你目前沒有登入,學習進度只存在這個瀏覽器。 Login 後,進度會跟著帳號,換電腦也看得到。