iT邦幫忙

2026 iThome 鐵人賽

DAY 11
0
Vibe Coding

《我與 AI 的奇幻漂流:30 天,把「能跑」變成「能上線」》系列 第 11 篇

【Day 11|留下備註】網址參數:重新整理之後,為什麼我的選擇消失了?

  • 分享至 

  • xImage
  •  

昨天每張專輯都有了自己的網址。今天換一個情境。

我在專輯列表搜尋「NewJeans」,再把年份篩成 2024,終於只剩下她們那一年發行的兩張專輯。結果一按重新整理——條件全部消失,又回到完整列表。 或是換一個情境:我想把這組結果傳給朋友,複製現在的網址跟他說「你看這幾張」。結果他打開之後,看到的還是沒有搜尋、沒有篩選的完整列表。
https://ithelp.ithome.com.tw/upload/images/20260925/20178017AcqpIgvr4Y.png
【圖 1|搜尋加篩選之後,網址完全沒變】

還有昨天留下來的那一個:點了 Superbeing 版,畫面換了,但網址還停在專輯本身。
https://ithelp.ithome.com.tw/upload/images/20260925/20178017SfpREeSh8r.png
https://ithelp.ithome.com.tw/upload/images/20260925/201780171RfKn8Wy2v.png
【圖 2、3|切換版本,網址也沒變】

這幾件事的共同點是:畫面上發生的事情,網址完全不知道。

今天,就來讓網址也記得這些事情。


一、地址後面的那張備註

昨天拆鐵人賽的網址時,有一段刻意先跳過了:

https://ithelp.ithome.com.tw/2026ironman/signup/list?group=vibe-coding

昨天處理的是中間的路徑:

/2026ironman/signup/list

今天要看的是最後這段:

?group=vibe-coding

它的意思是「在報名列表裡,只看 Vibe Coding 組」。

如果把昨天的路徑想成地址,參數就很像地址後面附的一張備註。地址決定你去哪裡;備註補充的是:到了之後,我想怎麼看。

拿這個網址來說:

地址:去鐵人賽的報名列表
備註:只看 Vibe Coding 組

試著把 ?group=vibe-coding 刪掉再打開,你還是會在報名列表,只是變回所有組別都顯示。

在這個例子裡,把備註撕掉之後,主要的目的地沒有變,只是少了一個條件。

所以可以先用這個方法判斷:拿掉之後,如果還是同一個主要內容、只是少了一個條件,通常比較適合放參數;如果連主要對象都變了,通常比較像路徑。

這只是一個好用的判斷方式,不是 Web 的硬規則——第三節會看到不同網站其實有不同選擇。

1.1 問號後面怎麼讀?

先看剛剛那一個:

?  group  =  vibe-coding
   └名稱┘    └─── 值 ───┘
  • ?:從這裡開始是參數
  • group:參數的名稱
  • vibe-coding:參數的值

如果不只一個,就用 & 接下去。例如在 Google 搜尋:

https://www.google.com/search?q=iphone&hl=zh-TW

可以讀成:

q=iphone       搜尋 iphone
hl=zh-TW       介面用繁體中文

同一個搜尋頁,帶了兩個條件。& 讀作「而且」就好。

另外,如果你在 Google 搜尋「耳機」,有時候複製出網址會看到:

?q=%E8%80%B3%E6%A9%9F

瀏覽器可能還是把網址顯示成中文,但在網址實際傳遞時,中文和部分特殊字元會經過 URL encoding,所以才會出現 %E8... 這種形式。這不是壞掉,只是網址表示文字的一種方式。

1.2 還有一種符號:#

你可能也看過網址裡有 #,例如維基百科:

https://en.wikipedia.org/wiki/K-pop#History

它叫片段,用來跳到頁面裡的某個位置——打開這個網址,會直接捲到「History」那一節。

它跟參數最大的差別是:# 後面的東西不會送到伺服器,只有瀏覽器自己知道。

用地址來說,它像是信封角落寫著「給二樓的小明」:郵差只負責把信送到這個門牌,至於要拿給屋裡的誰,是家裡的人收到信之後自己處理的——郵差根本不看這行字。

今天不會用到它,知道它不是參數就好。


二、這些東西,該記在哪?

在動手之前,先把今天真正的問題問清楚。

搜尋條件、篩選、目前看的版本、收藏⋯⋯這些東西都要「被記住」。但它們能被記住的地方有好幾個,而且各自解決的問題不一樣:

放在哪裡 主要解決什麼 例子
畫面裡 這一刻畫面怎麼顯示 下拉選單有沒有展開
網址 這個畫面怎麼被還原、被分享 搜尋、篩選、版本
這台瀏覽器 這台裝置下次還記得什麼 深色模式、目前的收藏
資料庫 系統或帳號真正保存了什麼 之後的收藏、投稿、帳號資料

這四個不是一條「越來越永久」的路,而是不同用途的位置。所以要決定放哪裡,其實是在回答兩個不同的問題。

2.1 要不要放進網址?

重新整理之後,希望還原成同一個畫面嗎?把網址傳給別人時,希望他看到一樣的結果嗎?

兩題的答案都是「希望」,這個狀態就很適合放進網址。

搜尋和篩選就是典型的例子:

/albums?q=newjeans&year=2024

重新整理不會消失,複製給朋友,他也能看到同一組結果。

2.2 要不要長期保存?

另一個問題完全不同:

這個東西本身,要不要被長期記住?而且跟著某個使用者,到哪台裝置都在?

這時候才是在決定要不要存進瀏覽器,或是資料庫。

例如「我收藏了哪幾張專輯」,它不是一個畫面的條件,而是使用者自己的資料。現在它存在這台瀏覽器裡,換一台裝置就沒了;如果希望登入之後到哪裡都看得到,就得存進資料庫——那是第三幕的事。

網址記的是「現在怎麼看」;資料庫記的是「真的有哪些資料」。

2.3 同一個功能,可以兩個都用

這兩件事不是二選一。以收藏來說,之後很可能會同時用到兩個地方:

  • 資料庫記住「我收藏了哪幾張」
  • 網址記住「我現在在收藏頁裡,只看正規專輯」,像 /favorites?type=studio-album

一個負責東西本身,一個負責怎麼看它。


三、哪些該放進網址,哪些不要

很適合放:搜尋關鍵字、篩選條件、排序方式、第幾頁、目前看的版本。共同點是——重新整理或把網址交給別人時,通常希望看到同一個狀態。

通常不用放:很短暫的 UI 狀態,例如滑鼠正在 Hover 哪張卡片、下拉選單此刻有沒有展開、按鈕正在 Loading。除非產品真的有「直接還原這個狀態」的需求,否則沒必要讓網址也記住。

不該放敏感資訊:密碼、登入權杖、私密個資等。網址可能出現在瀏覽紀錄、伺服器紀錄,也很容易被複製或分享出去,所以不能把它當成秘密空間。

至於昨天的 Drawer,也不需要再另外加一個 drawer=open。現在「哪張專輯被打開」已經由 /albums/[slug] 表示,同一件事沒必要記兩次。

3.1 這件事沒有標準答案

講完規則,要老實說一句:路徑和參數的界線,各家做法都不一樣。

看 Apple 官網的搜尋:

https://www.apple.com/tw/search/iphone?src=globalnav
                                └關鍵字┘

https://ithelp.ithome.com.tw/upload/images/20260925/20178017tIyWskC9hE.png
【圖 4|Apple 官網將搜尋的關鍵字放在路徑中】

Apple 把搜尋關鍵字放進路徑;Google 搜尋則常用 ?q=iphone。YouTube 一般影片網址會看到 ?v=xxxx,Shorts 又使用 /shorts/xxxx。

相近的需求,不同產品也可能做出不同的 URL 設計。

所以與其背「什麼一定要放哪裡」,不如先問兩件事:

  1. 它是不是一個穩定、值得被單獨指出來的主要內容? 是的話,傾向路徑
  2. 條件會不會自由組合? 會的話,參數通常更方便。像「關鍵字+類型+排序」可以任意搭配、誰先誰後也不重要,硬塞進路徑就得規定順序,還要處理沒選的時候怎麼辦

這個專案裡,我選擇把搜尋和篩選放進參數:它們不是一個需要獨立網址的主要內容,而且關鍵字、年份、類型、排序都可能自由組合。

3.2 順帶一提:不是每個參數都會改變畫面

回頭看 Apple 那個網址的後半段:

?src=globalnav

它沒有改變這次搜尋結果,比較像是一個來源標記:記錄這次操作是從哪個入口發生的。

網站常會用這類參數做分析,例如比較使用者從不同入口、活動或廣告進站之後的行為。你常看到的 utm_source=... 也是類似用途,之後有機會講數據分析或流量來源時還會再遇到。

所以參數其實有兩種用途:一種會改變你看到什麼,一種只是附帶記錄一些資訊。 今天要做的都是前者。


四、讓網址記住版本

先從昨天留下來的那個開始,因為它最單純。

現在在《Armageddon》的詳情頁切到 Superbeing 版,畫面換了,但只要按重新整理,就會跑回預設的版本。版本這件事,目前只活在畫面裡。

用第二節的兩個問題來看:重新整理之後,希望還是 Superbeing 嗎?希望。把網址傳給朋友時,希望他直接看到 Superbeing 嗎?也希望。所以版本很適合被寫進網址。

至於換一台裝置之後要不要「記得我上次看的是哪個版本」,那是另一個問題,跟今天要做的 URL state 不一樣。

那要放路徑還是參數?用第一節的方法,把它撕掉看看:拿掉版本,還是同一張專輯,只是回到預設版本。目的地沒變,所以是備註,我選擇放參數。

如果選擇放到參數,網址可能會變這樣:

/albums/aespa-armageddon?version=superbeing

4.1 名稱可以自己取

參數名稱是網站自己定的。version、ver、v 對瀏覽器來說都只是名稱。

這裡的取捨比較像:要短,還是要一眼看懂?

這個專案中我選擇用 version,因為比起少幾個字,我更希望看到網址的人馬上知道它代表什麼。

真正重要的是:整個產品要用同一套命名。 如果這件事有要求,就應該寫進 prompt,而不是每次讓 AI 自己選。

4.2 按上一頁,會發生什麼事?

網址變了,不一定會留下一筆瀏覽紀錄。瀏覽器的上一頁,其實是在翻一疊紀錄:你每到一個網址,它就在最上面疊一張;按上一頁,就是往回翻一張。

而改網址的時候,有兩種方式:新增一筆紀錄,疊上一張新的,按上一頁會回到剛剛的網址;或是替換目前這一筆紀錄,把最上面那張換掉,網址列一樣會變,但按上一頁會直接回到更早之前的那一頁。

類似的情況常出現在登入後的跳轉:有些網站會選擇替換掉那一筆紀錄,避免使用者按上一頁又回到登入畫面。

所以這裡有一個畫面上看不出來、但要自己決定的地方:切換版本時,要新增一筆,還是替換目前這一筆?

做法 切了五個版本之後按上一頁
每切一次就留一筆 要按五次,才回得到列表
只替換目前這一筆 按一次就回到列表

兩種在畫面上完全一樣,只有按上一頁才會發現差別。版本切換我選後者——使用者會把「切版本」當成同一頁裡的查看狀態,而不是一次新的瀏覽。

這也是一個很典型的「看起來能跑,但操作起來才知道對不對」的地方。


五、讓網址記住搜尋和篩選

5.1 這兩個其實不是同一件事

它們常常一起出現,所以很容易混在一起,但問的問題不一樣:

在問什麼 例子
搜尋 我要找什麼? ?q=aespa
篩選 這一堆裡面,我只想看哪些? ?type=studio-album&year=2024

搜尋是拿一段文字去比對;篩選是資料本來都在,只是把不符合的先收起來。介面上可以擺在一起,但背後是兩件事。

目標是讓它們都寫進網址:

/albums?q=newjeans&year=2024&sort=newest

參數的名稱和值,我都統一用英文。理由跟 Day 9 定 slug 一樣:中文會被編碼成一長串 %E8...,複製出去不好讀,也不好除錯。(使用者輸入的搜尋關鍵字當然可以是中文,那是他的內容;但像 type、sort 這些由網站定義的值,就用英文。)


六、請 AI 動手

前面決定的事情,現在整理成 prompt。我分兩輪做。

6.1 第一輪:版本參數

以下是我給 Codex 的提示詞:

目前專輯詳情頁的版本切換只存在畫面上,重新整理就消失。請把它同步到網址參數:

  • 網址格式 /albums/[slug]?version=...
  • 切換版本時網址跟著更新,但頁面不要整個重新載入,也不要新增瀏覽紀錄(替換目前這一筆就好)
  • 直接打開帶 version 的網址時,顯示對應的版本
  • version 不存在時,回到預設版本並把該參數移除
  • 不要改動 /albums/[slug] 的路由結構
  • 只保留版本這個參數,不要把其他參數帶進來
  • 這一輪先不要處理搜尋、類型、年份
  • 不要自行更改參數名稱;如果需要新的網址規則,先提出來讓我確認

開始修改前,先說明你的實作方式和預計修改哪些檔案。或是說你在這方面有更好的建議、有需要我做決定的部分,也可以跟我說。

重點不是 prompt 寫得多漂亮,而是先把這一輪要改的範圍縮小——版本做完、確認能動,再處理列表。出問題的時候,也比較容易知道是哪一步壞的。

6.2 第二輪:搜尋與篩選參數

以下是我給 Codex 的提示詞:

接著幫我把專輯列表的搜尋與篩選同步到網址參數:

  • 關鍵字用 q、年份用 year、類型用 type、排序用 sort
  • 頁面載入時,要從網址還原目前的搜尋與篩選條件
  • 搜尋文字可以即時更新結果與網址,但打字過程使用 replace,不要讓每個字都新增一筆瀏覽紀錄
  • 年份、類型、排序等明確的篩選操作使用 push,讓上一頁可以回到上一組條件
  • 清除某個條件時,對應的參數也要從網址移除;全部清除後回到乾淨的 /albums
  • 搜尋不到結果時顯示空狀態,並提供「清除篩選」
  • 從列表點進專輯時,不要把只屬於列表的搜尋與篩選參數帶到詳情頁
  • 不要把捲動位置、動畫、Hover 等暫時 UI state 放進網址
  • 保留目前的列表版面,不要順便重做
  • 不要自行更改既有參數名稱;如果需要新的網址規則,先提出來讓我確認

開始修改前,先說明你的實作方式和預計修改哪些檔案。或是說你在這方面有更好的建議、有需要我做決定的部分,也可以跟我說。

「不要順便重做版面」是經驗談:這一輪處理的是網址,不是版面。不講清楚的話,AI 有機會順手把整個列表重畫一次。


七、驗收

測什麼 應該要
網址可以記錄所查看的版本 網址隨版本改變
在詳情頁切換版本後重新整理 還停在同一個版本
連續切換幾個版本後按上一頁 直接回到列表,不是一個一個版本倒退
搜尋加篩選之後按重新整理 條件還在,結果一樣
複製網址貼到無痕視窗 看到一樣的結果
按上一頁 回到上一組條件,不是離開網站
清除全部篩選 網址也跟著變乾淨
搜尋一個不存在的關鍵字 出現空狀態,而且有清除的按鈕

https://ithelp.ithome.com.tw/upload/images/20260925/20178017ffCMJfLKYy.png
https://ithelp.ithome.com.tw/upload/images/20260925/20178017pMb4JH0pHW.png
【圖 5、6|版本參數有確實寫入】

https://ithelp.ithome.com.tw/upload/images/20260925/20178017s2IRXhSj1t.png
【圖 7|將含版本參數的網址輸入到新的無痕視窗,會進入詳情頁且對應版本參數】

https://ithelp.ithome.com.tw/upload/images/20260925/20178017txhc1RGAsV.png
【圖 8|搜尋、篩選時,條件也確實寫入網址。將網址放入無痕視窗,可還原搜尋/篩選結果】


八、換個領域

今天做的兩件事,在別的產品上也到處都是。

同一個東西的不同看法,就像手機的版本可以長得像下面這樣:

/products/iphone-17?color=black&storage=256

還是同一台 iPhone,只是現在看的是黑色、256GB。

列表上的條件,就像搜尋和篩選,在各個領域可能會長這樣:

電商    /products?q=iphone&brand=apple&sort=price
後台    /orders?status=pending&from=2026-09-01
訂房    /hotels?city=tokyo&guests=2

地址都沒換,只是附上了一張備註。

判斷方式也都一樣:你會不會想把這個畫面傳給別人看?

會的話,那些條件就很值得考慮放進網址。不然你只能跟他說「你自己篩一下,先選待處理,再把日期調到九月」。


結語與明日預告

今天做的事,其實是把「畫面上發生的事」寫回網址裡。在那之前,你的操作只有自己知道;現在你可以把整個結果交給別人——一個網址,就是一份可以傳遞的畫面。

但有另一種東西,今天沒有解決:「我收藏了哪些專輯」這份資料,現在還只存在這台瀏覽器裡。

收藏頁當然可以有自己的網址,例如 /favorites;但「我到底收藏了哪些專輯」不能只靠網址保存,也不該只活在這台電腦上。搜尋條件適合跟著網址走;個人的收藏資料,則更適合跟著「人」走。 要做到這件事,就會需要帳號和資料庫——那是第三幕的事。


之前有提到,開發者工具可以模擬不同螢幕尺寸,也能幫忙測一些裝置條件,但它終究不等於真機。有一些操作,像是真正用手指操作、呼叫手機鍵盤、在不同瀏覽器與實際裝置上使用,還是可能冒出電腦上沒看到的問題。

明天我們會來解決這件事,我們會換一個角度:把網站放到真的手機上看。 真的拿手機來試一次。

我們明天見。


上一篇
【Day 10|標上座標】動態路由與 404:為什麼我傳出去的網址,只會回到首頁?
下一篇
【Day 12|下水試航】響應式設計與 ngrok 實機測試:開發者工具看不見的事
系列文
《我與 AI 的奇幻漂流:30 天,把「能跑」變成「能上線」》 共 17 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言