天天看點

[JS入門到進階] 手寫解析URL參數的工具,并部署。用起來又快又爽!

持續創作,加速成長!

這是我的專欄​​《前端入門到進階》​​,跟HullQin學前端,入門到進階!帶你進大廠!

背景

我們需要解析URL參數

  1. 工作中,常常要根據URL排查問題,其中最重要的一步就是解析它的參數,取到關鍵詞,然後才能去前端日志系統搜尋。
  2. 面試位元組跳動和阿裡巴巴時,都遇到了這樣的面試題:(不許查閱任何API,使用沒代碼提示的記事本)請手寫函數,可以解析URL中的參數。

解決思路

針對上文第一個場景,我們更常見的做法是,搜尋「URL解析」,然後找到網上免費的工具,輸入URL,能把參數都告訴我,還能幫我decode參數,非常友善。

但是這是存在問題的:

  • 我們把URL參數都暴露給了外網工具,一旦他們這個工具有上報,那麼你的URL參數可能就被外網擷取了。一旦URL中存有敏感token資訊、或者使用者個人資訊,都容易洩漏,不安全。
  • 很多免費解析的網站很卡,還充斥着廣告,體驗很差。

當然,這種小工具,肯定也有很多其他開發者自己實作了,但是我是有自己的定制化訴求的,這麼簡單,不如手撸一個!

是以,我花了一點點時間,完成了開發、部署,效果如下:

[JS入門到進階] 手寫解析URL參數的工具,并部署。用起來又快又爽!

如果URL格式錯誤,也會報錯,并保留上次的結果:

[JS入門到進階] 手寫解析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')      

運作結果如下:

[JS入門到進階] 手寫解析URL參數的工具,并部署。用起來又快又爽!

其中,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>​​​ 元素的值并送出這個更改時,​

​change​

​​ 事件在這些元素上觸發。和 ​​input​​​ 事件不一樣,​

​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會報錯,這裡不希望控制台報錯。

這樣互動邏輯就實作啦。

展現邏輯:輸出結果

  1. 最好把報錯輸出給使用者。
  2. 結果需要格式化展現。

是以,結果我們用​

​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​

​裡。

寫在最後

繼續閱讀