持續創作,加速成長!
這是我的專欄《前端入門到進階》,跟HullQin學前端,入門到進階!帶你進大廠!
背景
我們需要解析URL參數
- 工作中,常常要根據URL排查問題,其中最重要的一步就是解析它的參數,取到關鍵詞,然後才能去前端日志系統搜尋。
- 面試位元組跳動和阿裡巴巴時,都遇到了這樣的面試題:(不許查閱任何API,使用沒代碼提示的記事本)請手寫函數,可以解析URL中的參數。
解決思路
針對上文第一個場景,我們更常見的做法是,搜尋「URL解析」,然後找到網上免費的工具,輸入URL,能把參數都告訴我,還能幫我decode參數,非常友善。
但是這是存在問題的:
- 我們把URL參數都暴露給了外網工具,一旦他們這個工具有上報,那麼你的URL參數可能就被外網擷取了。一旦URL中存有敏感token資訊、或者使用者個人資訊,都容易洩漏,不安全。
- 很多免費解析的網站很卡,還充斥着廣告,體驗很差。
當然,這種小工具,肯定也有很多其他開發者自己實作了,但是我是有自己的定制化訴求的,這麼簡單,不如手撸一個!
是以,我花了一點點時間,完成了開發、部署,效果如下:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICN4ETMfdHLkVGepZ2XtxSZ6l2clJ3LcBnYldHL0FWby9mZvwVPrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdsAjMfd3bkFGazxCMx8VesATMfhHLlN3XnxCMz8FdsYkRGZkRG9lcvx2bjxSa2EWNhJTW1AlUxEFeVRUUfRHelRHL2EzXlpXazxyayFWbyVGdhd3LcV2Zh1Wa9M3clN2byBXLzN3btg3PwJWZ35SN2cjMxIWM0kzM0gDZxMjZyYzXyUjM1ATMwEzLchDMyIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjLyM3Lc9CX6MHc0RHaiojIsJye.webp)
如果URL格式錯誤,也會報錯,并保留上次的結果:
網站加載速度很快,沒有廣告,沒有任何依賴,隻用了不到100行代碼。
解析速度很快,它是純前端邏輯,不涉及任何後端請求,安全性有保障。
體驗位址 & 源碼
體驗位址: tool.hullqin.cn/url-parser.…
源碼: github.com/HullQin/too…
實作方案
核心: 解析URL邏輯
解析URL,其實直接用URL即可。
畢竟解鈴還須系鈴人,URL規範是W3C定義的,我們用符合規範的工具來解析就好。手寫多累呀!
const url = new URL('https://tool.hullqin.cn/url-parser.html?key1=value1&key2&key3=1&key3=2&key3=3&key4=%7C%7C%7C')
運作結果如下:
其中,searchParams是URLSearchParams的執行個體,可以通過
forEach
周遊所有參數。
是以,得到url後,就可以這麼寫,擷取我們需要的參數了:
let result = '';
result += `host: ${url.host}\n`;
result += `path: ${url.pathname}\n`;
result += 'params:\n';
url.searchParams.forEach((value, key) => {
result += ` ${key}: ${value}\n`;
});
互動邏輯: 擷取輸入
定義好html:
<label for="url">請輸入待解析的URL:</label>
<br/>
<textarea id="url"></textarea>
然後擷取這個element後,給它添加
change
事件。每次失去焦點且内容改變後,就會觸發。
當使用者更改<input>、<select>和<textarea> 元素的值并送出這個更改時, 事件在這些元素上觸發。和 input 事件不一樣,
change
事件并不是每次元素的
change
改變時都會觸發。
value
const textareaEle = document.getElementById('url');
const urlOnchange = (event) => {
try {
const url = new URL(event.target.value.trim());
} catch {
}
}
textareaEle.addEventListener('change', urlOnchange);
這裡用了
trim
函數,是為了删除字元串首尾的空白符。
這裡加了個try catch。是因為如果你給的參數解析失敗new URL會報錯,這裡不希望控制台報錯。
這樣互動邏輯就實作啦。
展現邏輯:輸出結果
- 最好把報錯輸出給使用者。
- 結果需要格式化展現。
是以,結果我們用
pre
标簽展示,空格、換行符不需要轉義,也能展示出來。
<div id="message"></div>
<pre id="result"></pre>
const resultEle = document.getElementById('result');
const messageEle = document.getElementById('message');
const setUrl = (newUrl) => {
url = newUrl;
console.log(newUrl);
let result = '';
result += `host: ${newUrl.host}\n`;
result += `path: ${newUrl.pathname}\n`;
result += 'params:\n';
newUrl.searchParams.forEach((value, key) => {
result += ` ${key}: ${value}\n`;
});
resultEle.innerText = result;
}
const urlOnchange = (event) => {
try {
messageEle.innerText = '';
setUrl(new URL(event.target.value.trim()));
} catch (e) {
messageEle.innerText = e.message;
}
}
textareaEle.addEventListener('change', urlOnchange);
這樣,每次輸入時,清空報錯,然後重新解析URL。如果有錯,就展示報錯資訊在
message
元素上。如果沒錯,就展示計算結果,展現在
result
裡。