---
# System prepended metadata

title: 第三週：網站系統環境全攻略
tags: [2025 VibeCoding 體驗營]

---

:::info
本文件連結：https://hackmd.io/pQ-XEDpgTGGKR7CMaUOweg
此為 2025 VibeCoding 公益體驗營課程資料，相關資源僅授權給該課程學員。
:::

# 第三週：網站系統環境全攻略
* 記得錄影 / screen flow

## 成就
* [本日 QA](https://discord.com/channels/801807326054055996/1428276857266110534/1441036086393704632)
* 小節作業 1135 份
* 主線任務 1244 份
* 每日任務 1500 人次打卡


## Node.js 後端環境建置
![vc-1](https://hackmd.io/_uploads/BJloY72xWg.jpg)




## 本課重點

這一堂課的目標：
「讓新手小白能理解：瀏覽器 → 後端 → 回傳 JSON 的整個流程，並親手開一個超迷你 Node 後端伺服器。」


* 安裝 [Node.js](https://nodejs.org/en)
* 透過 Node.js 執行 JS 檔案

## 一、用 VSCode 跑 Node 後端伺服器
 1.	在桌面或任一資料夾，新增一個資料夾 node-intro
 2.	用 VSCode 開啟這個資料夾
 3.	新增一個檔案 app.js
 4.	VSCode 下方找到「終端機」→ 開一個「整合終端機」
 5.	在終端機輸入（這堂課只需要這一行）`node app.js`
 6.	透過 Mac 的活動監視器、Win 系統資源管理員看看

###  開啟 Node 伺服器範例程式碼：
```
const http = require("http");

// 建立伺服器
const server = http.createServer(function (request, response) {
  response.writeHead(200, { "Content-Type": "text/plain; charset=utf-8" });
  response.write("<h1>這是從 Node.js 回來的文字內容</h1>");
  response.end();
});

// 開始監聽 8080 port
server.listen(8080, () => {
  console.log("✅ 伺服器已啟動：請在瀏覽器輸入 http://localhost:8080");
  console.log("❌ 要關閉請回到這個視窗按：Ctrl + C");
});

```

![截圖 2025-11-19 下午2.17.58](https://hackmd.io/_uploads/rkBQWyjebe.png)

![截圖_2025-11-19_下午2_27_35 (1)](https://hackmd.io/_uploads/rJGlVJoxZe.png)

## 二、什麼是 JSON？ 服務之間的國際語言]
* [簡報](https://gamma.app/docs/JSON--rrk12omcljzdp35?mode=doc)
![vc-3](https://hackmd.io/_uploads/B1md9mhl-g.jpg)





物件是什麼、陣列是什麼

## 三、什麼是網址請求([MDN](https://developer.mozilla.org/zh-TW/docs/Web/HTTP/Methods))
> [出處](https://medium.com/@lokeshchinni123/django-request-and-response-lifecycle-fae8f6467e3d)
![截圖 2025-01-21 凌晨12.37.08](https://hackmd.io/_uploads/ryxaig3P1l.png)


1. Chrome 發出網址，撈網頁資源請求：
    * Google 搜尋引擎：https://www.google.com/search?q=hello
    * 比價網：https://feebee.com.tw/s/jbl%20flip%207/?pl=300&ph=1200&infinite=1

2. 透過網頁上的互動，利用 JS 從背景發出資源請求：
    * 校長寫的 3C 篩選網站產品： [前台連結](https://gonsakon.github.io/frontend-profuctFilter/)、[repo](https://github.com/gonsakon/frontend-profuctFilter)。[後台連結](backend-profuctfilter.zeabur.app)、[repo](https://github.com/gonsakon/backend-profuctFilter)
    * 第四週的 API：[CWA 天氣預報](https://opendata.cwa.gov.tw/dist/opendata-swagger.html)



## 四：寫一個商品查詢後端服務，並用 Chrome 瀏覽器直接索取資源

* [chrome套件](https://chromewebstore.google.com/detail/jsonview/gmegofmjomhknnokphhckolhcffdaihd?hl=zh-HK&pli=1)


```node=
const http = require("http");
const url = require("url");

// 先準備 5 個 3C 產品
const products = [
  { id: 1, name: "手機", price: 12900 },
  { id: 2, name: "筆電", price: 32900 },
  { id: 3, name: "平板", price: 15900 },
  { id: 4, name: "耳機", price: 2990 },
  { id: 5, name: "螢幕", price: 6990 },
];

const server = http.createServer(function (req, res) {
  // 統一回應都是 JSON
  res.setHeader("Content-Type", "application/json; charset=utf-8");

  // Health API
  if (req.url === "/api/health" && req.method === "GET") {
    res.statusCode = 200;
    res.end(
      JSON.stringify({
        status: "OK",
        timestamp: new Date().toISOString(),
      })
    );
    return;
  }

  // 首頁：列出簡單的 API 介紹
  if (req.url === "/" && req.method === "GET") {
    res.statusCode = 200;
    res.end(
      JSON.stringify({
        message: "歡迎使用 API 服務",
        description: "這是一個示範用的 3C 產品查詢 API。",
        endpoints: {
          health: {
            path: "/api/health",
            method: "GET",
            description: "檢查 API 是否正常運作",
          },
          products: {
            path: "/api/products?min=5000&max=20000",
            method: "GET",
            description: "用價格區間篩選產品（min / max 都是選填）",
          },
        },
      })
    );
    return;
  }

  // 其他路徑用 url.parse 來處理（例如 /api/products?min=...&max=...）
  const parsedUrl = url.parse(req.url, true);

  // 只處理 /api/products 這個路徑
  if (parsedUrl.pathname === "/api/products" && req.method === "GET") {
    // 取得 query 參數：?min=5000&max=20000
    const min = Number(parsedUrl.query.min) || 0;
    const max = Number(parsedUrl.query.max) || Infinity;

    // 篩選出在區間內的產品
    const matched = products.filter(function (p) {
      return p.price >= min && p.price <= max;
    });

    // 準備要回傳的 JSON
    const result = {
      min,
      max,
      totalProducts: products.length,
      matchedCount: matched.length,
      matchedProducts: matched, // 如果只想教「數量」，這行也可以先拿掉
    };

    res.statusCode = 200;
    res.end(JSON.stringify(result));
    return;
  }

  // 其他沒對到的路徑
  res.statusCode = 404;
  res.end(JSON.stringify({ message: "找不到路徑" }));
});

server.listen(8080, () => {
  console.log("Server running at http://localhost:8080");
});
```

可以改改看這兩個參數

```
http://localhost:8080/products?min=5000&max=20000
```

![截圖_2025-11-19_下午3_55_53](https://hackmd.io/_uploads/HkqtOeilbe.png)


## 四：寫一個前端、去介接我的後端伺服器

* [前台連結](https://gonsakon.github.io/frontend-profuctFilter/)、[repo](https://github.com/gonsakon/frontend-profuctFilter)
* [後台連結](backend-profuctfilter.zeabur.app)、[repo](https://github.com/gonsakon/backend-profuctFilter)

![截圖 2025-11-19 下午4.19.40](https://hackmd.io/_uploads/BksoalolZe.png)


## 主線任務

[主線任務連結](https://rpg.hexschool.com/#/training/12062817613394040615/board/content/12062817613394040616_12062817613394040632?tid=12062817613394040687)


## 備註

1. 之後會提供 Docker 部署到 Zeabur 的上傳教學
2. 下禮拜會加碼 Google excel API，做一個讀取資料庫！！！[範例](https://docs.google.com/spreadsheets/d/1v58ErLD5yPhIpitnOXnDevjjtFNz2d0SxuloR7g6qOY/edit?usp=sharing)、[網址](https://gonsakon.github.io/disaster-prep-calculator/index-googlesheet.html)、[repo](https://github.com/gonsakon/disaster-prep-calculator)、[題詞](https://gemini.google.com/share/b09f0c1c27ca)