Copyright © 2008 ~ 2024 MUKI space* / omegaBook theme All Rights Reserved.

發生的情境

▼ 假設今天有一段內容如下,需要在網站上換行顯示,同時要支援多語系:

// 中文
你送的禮物,在此刻好體貼<br />
陪我回憶,把過往走一遍

// 英文 (ChatGPT 翻譯的,請勿細看挑錯 XD)
The gift you gave is so thoughtful at this moment<br />
Accompany me to recall and go through the past

用 v-html 的寫法

▼ 比較直覺的寫法,是在語系加上 HTML 標籤,例如:

const message = {
  zh: {
    content: "你送的禮物,在此刻好體貼<br />陪我回憶,把過往走一遍"
  }

  en: {
    content: "The gift you gave is so thoughtful at this moment<br />Accompany me to recall and go through the past"
  }
}

▼ 然後在 template 使用 v-html

<template>
	<div v-html="message"></div>
</template>

但這樣寫就很容易受到 XSS 攻擊

跨網站指令碼(英語:Cross-site scripting,通常簡稱為:XSS)是一種網站應用程式的安全漏洞攻擊,是代碼注入的一種。它允許惡意使用者將程式碼注入到網頁上,其他使用者在觀看網頁時就會受到影響。這類攻擊通常包含了HTML以及使用者端手稿語言

XSS攻擊通常指的是通過利用網頁開發時留下的漏洞,通過巧妙的方法注入惡意指令代碼到網頁,使使用者載入並執行攻擊者惡意製造的網頁程式。這些惡意網頁程式通常是JavaScript,但實際上也可以包括JavaVBScriptActiveXFlash或者甚至是普通的HTML。攻擊成功後,攻擊者可能得到更高的權限(如執行一些操作)、私密網頁內容、對談cookie等各種內容。

跨網站指令碼 - wiki 百科

▼ 而且 console 也會報錯:

Vue i18n 推薦的替代寫法

為了避免 XSS 攻擊,我們可以改用替換的寫法,也就是在語系接收到 ${0} 這樣的參數,再在 template 把參數替換成你要的 HTML 標籤

官方有完整的寫法,分享了如何替換超連結 <a>,那我就針對前述的例子,寫一遍該如何替換

▼ 首先將語系內的 <br /> 改成用參數 ${0} 表示

const message = {
  zh: {
    content: "你送的禮物,在此刻好體貼${0}陪我回憶,把過往走一遍"
  }

  en: {
    content: "The gift you gave is so thoughtful at this moment${0}Accompany me to recall and go through the past"
  }
}

▼ 接著使用 <i18n-t> 替換參數

  • keypath:語系的位置
  • tag:包住整段語系(這邊為 message)的標籤,不會替換 ${0}
  • 裡面的 <br />:這個 <br /> 才是用來替換 ${0} 的標籤唷
<template>
  <i18n-t keypath="message" tag="p" scope="global">
    <br />
  </i18n-t>
</template>

▼ 最後渲染出來的語法如下:

<p>
  你送的禮物,在此刻好體貼<br />
  陪我回憶,把過往走一遍
</p>

結語

用替換參數的寫法,就能避免直接將 HTML 標籤暴露在外面,也能防止被有心人士攻擊。

大家可以檢查一下自己維護的網站,是否也有類似的情況發生?有的話不妨試試看這種寫法,增加網站的安全性喔。

歡迎給我點鼓勵,讓我知道你來過 :)

7
1
Subscribe
Notify of
guest

0 則留言
Inline Feedbacks
View all comments