STEP GUIDE · Solution

這個步驟要做什麼、改哪裡、怎麼看結果

這一步聚焦 TASK-03;下方只比較「Checkpoint 2 → Solution」的真實異動。

01

三項 Task 進度

TASK-01已完成

建立 mock 或 GAS 請求函式

預計修改:script.js

完成後:頁面能取得固定欄位的回應

TASK-02已完成

正規化並安全顯示 Sheet rows

預計修改:script.js

完成後:空值與 Live 文字都以安全文字節點顯示

TASK-03本步驟處理

顯示資料模式與失敗備援

預計修改:script.js

完成後:畫面區分 mock、空資料、合法 GAS /exec 與其他 JSON,live 失敗時可改用備援

02

HTML、CSS、JavaScript 與文件實際異動

展開檔案卡查看必要差異;只有程式碼區可以橫向捲動。

HTML本步驟無異動

檔案:index.html

修改前

前一步與本步驟沒有實質差異。

修改後

本步驟不需修改此語言。
CSS本步驟無異動

檔案:style.css

修改前

前一步與本步驟沒有實質差異。

修改後

本步驟不需修改此語言。
JavaScript本步驟有異動

檔案:script.js

修改前

  status.textContent = "尚未完成載入流程";

修改後

function isGasExecUrl(value) {
  try {
    const url = new URL(value);
    return url.protocol === "https:"
      && url.hostname === "script.google.com"
      && /^\/macros\/s\/[^/]+\/exec$/.test(url.pathname);
  } catch {
    return false;
  }
}
function getSourceLabel(url) {
  if (url === "mock") return "MOCK 備援";
  if (url === "mock-empty") return "MOCK 空資料";
  return isGasExecUrl(url) ? "LIVE GAS" : "CUSTOM JSON(非 GAS)";
}
  const url = endpoint.value.trim() || "mock";
  mode.textContent = getSourceLabel(url);
  status.textContent = "載入中…";
  try {
    const rows = normalizeRows(await requestRows(url));
    renderRows(rows);
    status.textContent = rows.length === 0 ? "載入完成,目前沒有資料" : `載入 ${rows.length} 筆`;
  } catch (error) {
    mode.textContent = "MOCK 備援";
    const rows = normalizeRows(await requestRows("mock"));
    renderRows(rows);
    status.textContent = `Live 失敗,已切備援:${error.message}`;
  }
README/其他文件本練習未使用

檔案:README.md

修改前

本練習沒有這個檔案。

修改後

本步驟不需修改此語言。
03

怎麼看到結果

  1. 準備

    先以 mock 模式操作;測 live 前再準備可用的 GAS 網址。

  2. 操作

    依序輸入 mock、mock-empty 與非 GAS 的可用 JSON URL,確認顯示正確來源與空資料提示,而且只有合法 HTTPS GAS /exec 會標成 LIVE GAS;最後輸入 missing.json 確認切回 MOCK 備援並顯示原因。

  3. 預期

    來源標示不冒充 LIVE GAS,空資料明確可讀,失敗時可改用備援

Solution TASK-03

顯示資料模式與失敗備援

完成後可見:畫面區分 mock、空資料、合法 GAS /exec 與其他 JSON,live 失敗時可改用備援

MOCK 備援

Sheet 產品資料

輸入 mock、mock-empty,或教師提供的 HTTPS GAS /exec URL;其他網址不會標成 LIVE GAS。

尚未載入