替留言板或聊天室增加超連結(autolinker)

今天不講日語,來記錄一下程式的東東。在使用留言板或是聊天室時,如果輸出的內容沒有超連結可以直接點會非常不方便,這篇使用 autolinker 這個套件,做一個簡易的範例。下面的範例使用 TypeScript,主要有 3 個步驟:

  • 抓取 DOM
  • 監聽輸入內容
  • 使用 autolinker 並輸出

建立 HTML 並抓 DOM

HTML 結構非常單純:

<div class="container">
  <h2>輸出結果</h2>
  <p class="result-text"></p>
</div>

<hr>

<textarea placeholder="請輸入聊天內容"></textarea>
替文字增加超連結 HTML
很單純的 HTML 畫面

接著抓輸入及輸入的兩個 DOM:

const resultText = document.querySelector('.result-text') as HTMLParagraphElement
const textarea = document.querySelector('textarea')! as HTMLTextAreaElement

監聽 textarea

我希望在按 enter 後能夠把資料渲染到上方,所以針對 textarea 做監聽,事件是 keypress

因為必須要知道按下去的按鍵是不是 enter,所以判斷 keyCode 是不是等於 13。如果是 13 的話,幫我添加連結。

textarea.addEventListener('keypress', (e: KeyboardEvent) => {
  const { keyCode } = e;

  if (keyCode === 13) {
    // 幫我添加連結
  }
})

使用 autolinker 增加連結

使用 autolinker 之前記得先安裝,我是用 npm,所以打:

npm install autolinker --save

並且引入套件:

import Autolinker from 'autolinker';

再寫一個 function 來處理連結:

function addLink<T extends string>(text: T): T {
  const linkText = Autolinker.link(text, {
    newWindow: true,
    sanitizeHtml: true
  })

  return linkText as T;
}

傳入參數 text,接著透過 Autolinker 轉換後回傳。 如果在 textarea 內輸入「hello!! https://google.com」則會回傳: hello!! <a href="https://google.com" target="_blank" rel="noopener noreferrer">google.com</a>

所以回到 textarea 的事件監聽裡,我們把程式碼補上:

if (keyCode === 13) {
  // 塞到畫面上
  resultText.innerHTML = addLink(textarea.value); 
  // 清空輸入內容
  textarea.value = '';
  // 避免按 enter 後換行
  e.preventDefault();
}

完成結果如下:

替文字增加超連結 輸出結果

XSS 的問題

你可能有注意到如果輸入 HTML 是可以直接被選染的,代表可以打 <script>alert(0)</script> 上去。所以才在轉換的時候加上 Autolinker 提供的 sanitizeHtml: true,避免 XSS 的發生。

const linkText = Autolinker.link(text, {
  newWindow: true,
  sanitizeHtml: true
})

autolinker 還有其他不少功能,在這個範例中並沒有用到,其他功能可以到 Github 看他們的文檔。

發表迴響