前言

問題

專案中使用 golang + gin 開發網站,並且有使用 JSON-LD,然而 JSON-LD 中的「&」字符卻預期外的被替換成了「\x26」。


問題程式碼

發生問題的程式碼如下。

相關問題

經過一番搜尋,發現 Golang「Hugo」框架也有一樣的問題,Hugo 可以透過 {{ printf "\"%s\"" .Title | safeJS }} 解決。有興趣的朋友可以參考下方連結。

Problems with encoding special characters in json+ld (“invalid escape sequence”)

追查問題所在

gin 使用 (gin.Context) HTML 方法渲染網頁,而深入追查至最後,可以發現 gin 是使用 html/template 進行渲染。

因此我們經由下方程式碼追查 html/template 後,發現問題不單純是 gin 框架造成,

而是 html/template 原本就有這樣的問題,而 gin 使用了 html/template 進行渲染。

追蹤 Hugo解決方案

深入追查後,發現 Hugo 的「safeJS」解決方案是框架中加入的 template FuncMap,

此方法引用了「github.com/spf13/cast」套件,而 cast 套件正是為了 Hugo 而開發的。

為此我們撰寫了下列程式測試 cast,並且確實成功打印了「&」符號。

我們可以從程式碼中看到,其實「safeJS」只是 Hugo 框架利用 cast 將輸入值轉為字串,最終輸出為 template.JS,並且上述的解決方案還還有一個步驟,就是將雙引號一起透過 template.JS 轉換後打印,若我們將 cast 拿掉,程式如下

這邊我們得到一個結論:

html/template 在打印 script 時,若該字串被雙引號括著,則會被編碼

ex: 

"description": "{{.testTextWithAnd}}" ===> "description": "a \x26 b"

因此我們需要將渲染的參數事先加上雙引號,再交由 html/template 渲染。

若使用 text/template 則不會有此問題

FBLINETwitterLinkIn
回部落格