第 17 堂|讓表單讀到真正的服務資料

依提供的契約啟動後端,從實際API讀服務,分開載入中、空資料與失敗。

3 小時 · 六個步驟 · 54 分鐘觀念+126 分鐘實作

自己已勾選 0/6 步
步驟 1/6 · 觀念 18 分鐘

API契約比猜路徑可靠

請求方法與services映射正確,選項來自實際JSON。

先準備

  • 自己的service-site/frontend既有inquiry.html、inquiry.js與完整styles.css;config.js本關才新增
  • 隨起始包提供的API_CONTRACT.html、START_HERE.html;先啟動後端再開/api/services記錄JSON,不附管理密碼
  • 自己的後端根網址;啟動後才填GET /api/services的實際200 JSON

契約列出方法、路徑與JSON外層。後端已提供,這堂先學啟動與讀取,不重寫伺服器或身份機制。

先分清自己的作品、線上畫面與可啟動參考包;線上參考不提供API,請在本機閱讀隨包OPEN_REFERENCE.html後操作。

一起拆解:從回應欄位做出選項

本關18分鐘觀念:3分鐘看輸入、6分鐘逐步推演、5分鐘正常與錯誤對照、4分鐘先預測再說明。

這次的輸入

自己的後端GET /api/services回200,JSON外層叫services。

{ "services":[{"id":"web","name":"網站設計"}] }
// option.value = item.id
// option.textContent = item.name

這段是觀念縮圖,完整可操作檔案在本關參考成果;請依當前階段判讀,不把片段直接貼到任意位置。

一步一步推演

  1. 先開後端API網址看JSON,記方法、路徑、狀態與外層;此時前端config.js尚待新增。
  2. 請AI新增公開config並串接GET,id作值、name作文字,不寫死顯示清單。
  3. 用manage更名web,重整前端應讀到新名稱,不能只改前端文字。

正常應看到

選單值仍web,顯示後端最新服務名;這堂尚未POST詢問。

常見錯誤對照

把payload.services寫成payload.serviceList會得到undefined,即使HTTP是200也無法渲染。

先預測,再說明原因

後端把名稱改掉但id不變,草稿選項應如何對應?

跟著觀察

  1. 先讀「從回應欄位做出選項」的輸入,指出本關實際檔案或資料。
  2. 後端把名稱改掉但id不變,草稿選項應如何對應?
  3. 依例子逐步說明正常結果與錯誤差別,再記下自己的預測;參考結果不是已完成的實測。

做完,自己確認

  • 請求方法與services映射正確,選項來自實際JSON。
  • 能指出指定檔案與作用範圍。
接著進行第 2 步
步驟 2/6 · 實作 42 分鐘

先讓前後端說同一種話

請求方法與services映射正確,選項來自實際JSON。

先準備

  • 自己的service-site/frontend既有inquiry.html、inquiry.js與完整styles.css;config.js本關才新增
  • 隨起始包提供的API_CONTRACT.html、START_HERE.html;先啟動後端再開/api/services記錄JSON,不附管理密碼
  • 自己的後端根網址;啟動後才填GET /api/services的實際200 JSON

親手讀HTML契約、啟動後端,在Network看一個真實GET。

跟著做

  1. 解壓完整service-site,依START_HERE設定自己的後端密碼並啟動。
  2. 請AI按契約在config.js與inquiry.js接GET /api/services,不留硬編清單。
  3. 用manage工具改web名稱再重載,核對前端來自後端。

串接真正的服務清單

主要使用 Cursor 內建 AI;先附資料,再送出指令。

1.附上這些檔案與資料
  • 自己的service-site/frontend既有inquiry.html、inquiry.js與完整styles.css;config.js本關才新增
  • 隨起始包提供的API_CONTRACT.html、START_HERE.html;先啟動後端再開/api/services記錄JSON,不附管理密碼
  • 自己的後端根網址;啟動後才填GET /api/services的實際200 JSON

本關才新增,不用先附檔:service-site/frontend/config.js。請讓 AI 建立在指定位置;收到程式碼時核對檔名後自行儲存。

2.貼到哪裡
  1. 在 Cursor 開啟自己的本關練習副本,進入內建 AI 對話;正常版與故障副本分開。
  2. 只用 @ 附上上方已存在的指定檔案;「本關才新增」的檔案不需要先找或先建空檔,再貼下方Prompt。
  3. 先讀回覆與差異,只保存指定範圍;回到瀏覽器實際檢查。版本保存由自己操作,不讓 AI 代替驗收或提交。
3.預期回覆與操作
  • 請AI按契約在config.js與inquiry.js接GET /api/services,不留硬編清單。
  • 更名後前端重載讀到新名稱,沒有硬編假成功。
4.自己檢查結果
  • 請求方法與services映射正確,選項來自實際JSON。
  • 更名後前端重載讀到新名稱,沒有硬編假成功。
串接真正的服務清單 Prompt(可收合)

你是協助零基礎學員的網站開發助手。我使用 Cursor 免費版編輯原生 HTML、CSS、JavaScript;必要時把你提供的內容手動貼入檔案。

情境與本次輸入:從第16堂正常service-site/frontend承接;起始包已附真實Node.js22+後端、API_CONTRACT.html與START_HERE.html,無第三方套件。後端預設127.0.0.1:8780,資料在frontend外backend/.data。GET /api/services回200 {services:[{id,name}]},空陣列與503失敗不同。config.js只放公開apiBase;請求credentials:include,來源需後端明確允許,不用no-cors。APPA、紫綠tokens與五欄草稿保留。這堂只讀服務,尚未POST詢問。

本次任務:起始版已存在的檔案才需附上;本關新增service-site/frontend/config.js,不要要求先附不存在的檔案。依提供API_CONTRACT.html與START_HERE.html,只串接GET /api/services。回應200外層services陣列,每筆id/name;id放option.value、name以textContent顯示,不保留硬編的三項假清單。config.js僅放公開apiBase http://127.0.0.1:8780,不放秘密;fetch credentials:include,不用no-cors。載入中先清舊選項、禁用選擇與送出,姓名Email主旨需求保留。保持五欄驗證、草稿與APPA,這堂不POST。指出實際檔案與JSON映射,更新入口文案讓讀取與送出階段清楚;列後端更名後前端重載的驗收。

請先閱讀我附上的相關檔案或資料,資訊缺漏時精確列出需要補充的項目,不猜檔名、API 或測試結果。說明以繁體中文撰寫,指出檔案與修改位置;檢查結果區分已知、待驗與未完成。只處理學生自己的練習副本,不改現有展示網站,不要求付費訂閱。
Cursor AI 無法使用?改用 ChatGPT 備援

把上方指定的檔案內容、清單與補充資料,連同同一份 Prompt 貼入 ChatGPT 對話。只貼電腦上的路徑,無法讓它讀取你的檔案。

收到程式碼時,先核對檔名與修改位置,再手動存回自己的練習副本;若收到檢查表或補檔步驟,就逐項操作。不要把 Prompt 或程式碼框的反引號貼進 HTML/CSS。

兩邊都受限時,可先看既有參考成果、檢查差異與手動修改;未做過的 AI 生成或公開發布仍記待完成。不要貼入帳密、金鑰或真實個資。

複製只取得 Prompt 文字,檔案需自行在 Cursor 附上;本頁不會呼叫 AI 或自動完成關卡。

做完,自己確認

  • 請求方法與services映射正確,選項來自實際JSON。
  • 更名後前端重載讀到新名稱,沒有硬編假成功。

線上只看前端畫面;完整操作請下載。本頁不提供案件API。把參考包解壓到新的資料夾,先讀 OPEN_REFERENCE.html,再啟動隨包後端;不要覆蓋自己的作品或案件。

下載本關可啟動參考包

看參考包啟動與資料保留步驟

接著進行第 3 步
步驟 3/6 · 觀念 18 分鐘

200空陣列不等於503讀取失敗

空資料與失敗文字不同,載入及無服務不送出。

先準備

  • 自己的service-site/frontend/inquiry.html、inquiry.js、config.js與完整styles.css
  • 隨起始包提供的API_CONTRACT.html、START_HERE.html與實際Network紀錄;不附管理密碼
  • normal/empty/error實際回應與預期表

沒有服務時不能讓使用者選假資料;讀取失敗要保留文字並提供明確重試,不能偷偷退回靜態清單。

一起拆解:同樣沒選項,原因不同

本關18分鐘觀念:3分鐘看輸入、6分鐘逐步推演、5分鐘正常與錯誤對照、4分鐘先預測再說明。

這次的輸入

先正常讀到三項,再分別切services=empty與services=error。

200 {services:[]} → 沒有可選服務
503 {error:...} → 讀取失敗,可手動重試
讀取中 → 禁用選擇與送出

這段是觀念縮圖,完整可操作檔案在本關參考成果;請依當前階段判讀,不把片段直接貼到任意位置。

一步一步推演

  1. 先在第二終端依TEST_MODES切換;第一次啟動要有TEACHING_MODE=1。
  2. 每次載入先清舊選項並禁用操作;文字欄保留,不回退假清單。
  3. 回normal後按重試,確認三項恢復,原主旨及草稿仍在。

正常應看到

空資料、失敗與載入中提示可區分;不會把上次選項當最新成功。

常見錯誤對照

503時留著可送出的舊選項,可能使人誤認服務資料正常。

先預測,再說明原因

看到200且空陣列,應重登管理員還是告知目前無服務?

跟著觀察

  1. 先讀「同樣沒選項,原因不同」的輸入,指出本關實際檔案或資料。
  2. 看到200且空陣列,應重登管理員還是告知目前無服務?
  3. 依例子逐步說明正常結果與錯誤差別,再記下自己的預測;參考結果不是已完成的實測。

做完,自己確認

  • 空資料與失敗文字不同,載入及無服務不送出。
  • 能指出指定檔案與作用範圍。
接著進行第 4 步
步驟 4/6 · 實作 42 分鐘

把空資料與失敗分開

空資料與失敗文字不同,載入及無服務不送出。

先準備

  • 自己的service-site/frontend/inquiry.html、inquiry.js、config.js與完整styles.css
  • 隨起始包提供的API_CONTRACT.html、START_HERE.html與實際Network紀錄;不附管理密碼
  • normal/empty/error實際回應與預期表

親手記normal/empty/error各自預期,再依契約切模式。

跟著做

  1. 依契約由核准教學請求切換三種services模式。
  2. 請AI只加空資料、錯誤提示與手動重試,不改其他欄位。
  3. 填主旨再失敗重試,確認原值不清掉、恢復後讀到正確選項。

補齊服務載入狀態與重試

主要使用 Cursor 內建 AI;先附資料,再送出指令。

1.附上這些檔案與資料
  • 自己的service-site/frontend/inquiry.html、inquiry.js、config.js與完整styles.css
  • 隨起始包提供的API_CONTRACT.html、START_HERE.html與實際Network紀錄;不附管理密碼
  • normal/empty/error實際回應與預期表
2.貼到哪裡
  1. 在 Cursor 開啟自己的本關練習副本,進入內建 AI 對話;正常版與故障副本分開。
  2. 用 @ 附上本關指定檔案,核對完整路徑;補實際觀察、輸入與結果,再貼下方 Prompt。
  3. 先讀回覆與差異,只保存指定範圍;回到瀏覽器實際檢查。版本保存由自己操作,不讓 AI 代替驗收或提交。
3.預期回覆與操作
  • 請AI只加空資料、錯誤提示與手動重試,不改其他欄位。
  • 手動重試可恢復選項,文字與草稿不變。
4.自己檢查結果
  • 空資料與失敗文字不同,載入及無服務不送出。
  • 手動重試可恢復選項,文字與草稿不變。
補齊服務載入狀態與重試 Prompt(可收合)

你是協助零基礎學員的網站開發助手。我使用 Cursor 免費版編輯原生 HTML、CSS、JavaScript;必要時把你提供的內容手動貼入檔案。

情境與本次輸入:從第16堂正常service-site/frontend承接;起始包已附真實Node.js22+後端、API_CONTRACT.html與START_HERE.html,無第三方套件。後端預設127.0.0.1:8780,資料在frontend外backend/.data。GET /api/services回200 {services:[{id,name}]},空陣列與503失敗不同。config.js只放公開apiBase;請求credentials:include,來源需後端明確允許,不用no-cors。APPA、紫綠tokens與五欄草稿保留。這堂只讀服務,尚未POST詢問。

本次任務:只改善服務載入:200 services=[]顯示目前無可選服務並禁用選擇與送出;503或格式錯誤顯示失敗與重新讀取按鈕。重試重新GET,不自動不停重試、不回退硬編清單;載入中清舊選項並禁用操作,已填文字與草稿保留。保留正常id/name映射、config與五欄驗證,不接詢問POST。列normal/empty/error後恢復normal的實測與待測。

請先閱讀我附上的相關檔案或資料,資訊缺漏時精確列出需要補充的項目,不猜檔名、API 或測試結果。說明以繁體中文撰寫,指出檔案與修改位置;檢查結果區分已知、待驗與未完成。只處理學生自己的練習副本,不改現有展示網站,不要求付費訂閱。
Cursor AI 無法使用?改用 ChatGPT 備援

把上方指定的檔案內容、清單與補充資料,連同同一份 Prompt 貼入 ChatGPT 對話。只貼電腦上的路徑,無法讓它讀取你的檔案。

收到程式碼時,先核對檔名與修改位置,再手動存回自己的練習副本;若收到檢查表或補檔步驟,就逐項操作。不要把 Prompt 或程式碼框的反引號貼進 HTML/CSS。

兩邊都受限時,可先看既有參考成果、檢查差異與手動修改;未做過的 AI 生成或公開發布仍記待完成。不要貼入帳密、金鑰或真實個資。

複製只取得 Prompt 文字,檔案需自行在 Cursor 附上;本頁不會呼叫 AI 或自動完成關卡。

做完,自己確認

  • 空資料與失敗文字不同,載入及無服務不送出。
  • 手動重試可恢復選項,文字與草稿不變。

線上只看前端畫面;完整操作請下載。本頁不提供案件API。把參考包解壓到新的資料夾,先讀 OPEN_REFERENCE.html,再啟動隨包後端;不要覆蓋自己的作品或案件。

下載本關可啟動參考包

看參考包啟動與資料保留步驟

接著進行第 5 步
步驟 5/6 · 觀念 18 分鐘

欄位映射要對照實際JSON

200正確資料可顯示服務,錯誤與空資料仍有提示。

先準備

  • 自己的service-site/frontend/inquiry.html、inquiry.js、config.js與完整styles.css
  • 隨起始包提供的API_CONTRACT.html、START_HERE.html與實際Network紀錄;不附管理密碼
  • fault-L17完整inquiry.js、實際services JSON與錯誤狀態

故障程式讀serviceList,但實際契約叫services。先看回應再改一處,不重做後端或填假選項。

一起拆解:200不代表欄位名稱寫對

本關18分鐘觀念:3分鐘看輸入、6分鐘逐步推演、5分鐘正常與錯誤對照、4分鐘先預測再說明。

這次的輸入

故障副本Network有services,畫面卻顯示讀取失敗。

// 故障
const items = payload.serviceList;
// 本次契約
const items = payload.services;

這段是觀念縮圖,完整可操作檔案在本關參考成果;請依當前階段判讀,不把片段直接貼到任意位置。

一步一步推演

  1. 保存實際JSON與錯誤畫面,對照契約拼字。
  2. 只改items來源一處;陣列驗證與狀態處理都保留。
  3. 重跑normal、empty、error、重試及草稿,確認沒有補假資料。

正常應看到

正常資料重新出現,空與錯誤仍各有提示。

常見錯誤對照

改後端回傳serviceList只是在遷就錯誤前端,破壞全班契約。

先預測,再說明原因

驗收時除了看三項出現,還要重跑哪兩種非正常結果?

跟著觀察

  1. 先讀「200不代表欄位名稱寫對」的輸入,指出本關實際檔案或資料。
  2. 驗收時除了看三項出現,還要重跑哪兩種非正常結果?
  3. 依例子逐步說明正常結果與錯誤差別,再記下自己的預測;參考結果不是已完成的實測。

做完,自己確認

  • 200正確資料可顯示服務,錯誤與空資料仍有提示。
  • 能指出指定檔案與作用範圍。
接著進行第 6 步
步驟 6/6 · 實作 42 分鐘

回應有資料,為什麼沒有選項

200正確資料可顯示服務,錯誤與空資料仍有提示。

先準備

  • 自己的service-site/frontend/inquiry.html、inquiry.js、config.js與完整styles.css
  • 隨起始包提供的API_CONTRACT.html、START_HERE.html與實際Network紀錄;不附管理密碼
  • fault-L17完整inquiry.js、實際services JSON與錯誤狀態

手動圈出Network外層services與程式錯誤欄名。

跟著做

  1. 獨立fault-L17重現200卻顯示失敗。
  2. 請AI只修payload.services映射。
  3. 重驗讀取、更名、空與錯誤模式及原表單草稿。

修復服務回應欄位映射

主要使用 Cursor 內建 AI;先附資料,再送出指令。

1.附上這些檔案與資料
  • 自己的service-site/frontend/inquiry.html、inquiry.js、config.js與完整styles.css
  • 隨起始包提供的API_CONTRACT.html、START_HERE.html與實際Network紀錄;不附管理密碼
  • fault-L17完整inquiry.js、實際services JSON與錯誤狀態
2.貼到哪裡
  1. 在 Cursor 開啟自己的本關練習副本,進入內建 AI 對話;正常版與故障副本分開。
  2. 用 @ 附上本關指定檔案,核對完整路徑;補實際觀察、輸入與結果,再貼下方 Prompt。
  3. 先讀回覆與差異,只保存指定範圍;回到瀏覽器實際檢查。版本保存由自己操作,不讓 AI 代替驗收或提交。
3.預期回覆與操作
  • 請AI只修payload.services映射。
  • 只修一個欄位映射,不改契約與其他功能。
4.自己檢查結果
  • 200正確資料可顯示服務,錯誤與空資料仍有提示。
  • 只修一個欄位映射,不改契約與其他功能。
修復服務回應欄位映射 Prompt(可收合)

你是協助零基礎學員的網站開發助手。我使用 Cursor 免費版編輯原生 HTML、CSS、JavaScript;必要時把你提供的內容手動貼入檔案。

情境與本次輸入:從第16堂正常service-site/frontend承接;起始包已附真實Node.js22+後端、API_CONTRACT.html與START_HERE.html,無第三方套件。後端預設127.0.0.1:8780,資料在frontend外backend/.data。GET /api/services回200 {services:[{id,name}]},空陣列與503失敗不同。config.js只放公開apiBase;請求credentials:include,來源需後端明確允許,不用no-cors。APPA、紫綠tokens與五欄草稿保留。這堂只讀服務,尚未POST詢問。

本次任務:故障前端GET回200且JSON外層services有資料,但程式const items = payload.serviceList。依契約與實際JSON只改為payload.services,保留驗證陣列、loading/empty/error/retry、五欄與草稿。不改後端契約、不補假選項或no-cors,不宣稱未做的更名與異常測試通過。列一處diff與四種狀態回歸。

請先閱讀我附上的相關檔案或資料,資訊缺漏時精確列出需要補充的項目,不猜檔名、API 或測試結果。說明以繁體中文撰寫,指出檔案與修改位置;檢查結果區分已知、待驗與未完成。只處理學生自己的練習副本,不改現有展示網站,不要求付費訂閱。
Cursor AI 無法使用?改用 ChatGPT 備援

把上方指定的檔案內容、清單與補充資料,連同同一份 Prompt 貼入 ChatGPT 對話。只貼電腦上的路徑,無法讓它讀取你的檔案。

收到程式碼時,先核對檔名與修改位置,再手動存回自己的練習副本;若收到檢查表或補檔步驟,就逐項操作。不要把 Prompt 或程式碼框的反引號貼進 HTML/CSS。

兩邊都受限時,可先看既有參考成果、檢查差異與手動修改;未做過的 AI 生成或公開發布仍記待完成。不要貼入帳密、金鑰或真實個資。

複製只取得 Prompt 文字,檔案需自行在 Cursor 附上;本頁不會呼叫 AI 或自動完成關卡。

做完,自己確認

  • 200正確資料可顯示服務,錯誤與空資料仍有提示。
  • 只修一個欄位映射,不改契約與其他功能。

線上只看前端畫面;完整操作請下載。本頁不提供案件API。把參考包解壓到新的資料夾,先讀 OPEN_REFERENCE.html,再啟動隨包後端;不要覆蓋自己的作品或案件。

下載本關可啟動參考包

看參考包啟動與資料保留步驟

留下本堂檢查紀錄

留下自己的檢查紀錄

記下實際做過的操作、差異與結果。還沒做的項目寫「待完成」。

勾選與筆記只保存在這個瀏覽器。

重設只清除勾選,網站檔案與檢查筆記都保留。

帶著這一步,繼續往前。

保留正常作品與實際檢查紀錄;未完成的操作可以回來補做。

帶著作品,進入第 18 堂