跳至主要內容
儀器櫃/網路與生活← J01 · J03 →
J02

網址解析與清理

拆解網址每個部件、編輯 query,並一鍵移除 utm_ 這類追蹤參數再複製。

原理

解析本身交給瀏覽器的 URL 介面,因為那就是 WHATWG 的演算法,也就是「瀏覽器實際會怎麼看這串字」的定義。自己寫剖析器只會跟真實行為產生分歧。剩下的工作都是 URL 介面本身答不出來的問題。

查詢字串在這裡重新拆一次,不用 URLSearchParams。理由是它會把 ?a 與 ?a= 視為相同——前者沒有等號、後者有一個空值,而有些後端把這兩種當成不同的意思;它也不會告訴你同一個參數出現了兩次。?id=1&id=2 對不同框架的意義不一樣(取第一個、取最後一個、變成陣列),把它折疊起來剛好藏住某個請求行為詭異的原因,所以這裡照原順序保留每一筆,包含重複。

主機名稱那一欄有兩種寫法,因為國際化網域有兩種形式:瀏覽器實際連線用的是 Punycode 的 xn-- 形式,網址列顯示的是 Unicode。這裡自己實作了 RFC 3492 的編解碼,順便做一件事:如果某個標籤裡混用了拉丁、斯拉夫、希臘這三種長得很像的字母,就標出來。那是仿冒網域最常見的手法——把 apple 的 a 換成斯拉夫字母的 а,肉眼分不出來。

清理追蹤參數的清單來自各廣告平台自己的文件與 Firefox 的查詢字串清理設定。這種清單本質上會過期,廣告網路加參數比任何人更新清單都快,而且任何網站都可以讓其中一個變成必要參數,所以它在畫面上可以直接編輯。路徑則一律不動:大小寫不改、順序不排、不做正規化——/A 與 /a 是兩個不同的資源,一個會「順手整理」路徑的清理器會弄壞連結。

界線

  • 沒有 scheme 的字串會自動補上 https:// 再試一次,但只在開頭本來就長得像主機名稱的時候。ht!tp://x 不會變成 https://ht!tp//x——那會解析成功並且不是任何人的意思,錯誤答案比錯誤訊息糟糕得多。
  • Punycode 的實作是純 RFC 3492,沒有做 UTS-46 的映射與正規化,所以它不是完整的 IDNA。它可以告訴你 xn-- 標籤長什麼樣子、幫你看出混script的仿冒手法,但不要拿它的輸出當安全判斷的依據——真正的比對要在做過 UTS-46 之後才有意義。
  • 追蹤參數清單不是規範,是觀察。移除它們不會改變你拿到哪一頁——這些參數的作用是標記點擊來源而不是選擇內容——但如果某個網站真的把 utm_source 當成路由的一部分,清理過的網址就會壞掉。以網站的實際行為為準,不要以清單為準。
  • 這一頁不連任何地方。它不會去抓那個網址、不會跟隨重新導向、不會告訴你那個連結還活著。