Rails 字串處理 encode 及除錯
喜歡作者的文章嗎?馬上按「關注」,當作者發佈新文章時,思書™就會 email 通知您。
思書是公開的寫作平台,創新的多筆名寫作方式,能用不同的筆名探索不同的寫作內容,無限寫作創意,如果您喜歡寫作分享,一定要來試試! 《 加入思書》
思書™是自由寫作平台,本文為作者之個人意見。
文章資訊
本文摘自:
Categories:
Tags:
Date:
Published: 2018/07/08 - Updated: 2021/02/08
Total: 1976 words
給本文個喜歡
或不
關於作者
很久以前就是個「寫程式的」,其實,什麼程式都不熟⋯⋯
就,這會一點點,那會一點點⋯⋯
看看作者的其他文章
看看思書的其他文章
寫動態網頁,少不了就是字串變來變去,我們這篇來探討幾個很重要的關鍵:
字串跳脫
先說簡單的,在 Ruby 中,我們要如何處理字串內的單雙引號及換行等的特殊符號,看完以下實例就很清楚了:
HTML Escape / Unescape,中文叫「跳脫特殊字元」
主要用處就是將字串顯示在網頁,其實就是將 & " ' < > 這五種字元,轉來轉去,例如:
Escape 會變成:
使用上,如下:
如上面的實例:
URI encode,中文叫「網址編碼」
我們常會讀取網址,網址,一定是 ASCII 編碼,非 ASCII 字元(像是中日韓文),就會被 URI encode,也就是你常看到的那串 %E7%B6%B2,例如:
URI encode 會變成:
可以看到,我們在非英文的網址中,只有 Params 是要 encode 編碼的。
URI 如何編碼?Ruby 中的 URI 模組就很好用了:
附帶一提 JavaScript 有兩個相關的 function - encodeURI(), encodeURIComponent(),舊的 escape() 就不要用了
還有一個 HTML 動態網頁是常用的,就是如何:
移除字串中 HTML 標記及 ASCII 控制字元
很常,我們要將 HTML 的字串內容移除 HTML tags,這在 Rails 中超級簡單,例如:
我們常會在網頁上要顯示一小段原本是HTML編碼的字串,這時,就用以下這個:
這真的很好用,不用再 gsub 來來去去!
最討厭的是字串編碼
字串編碼真的是一件很煩人的事,電腦上的文字,有太多的歷史包袱了,說多了,就像白髮宮女話當年,也沒太多意義了,想要知道你可愛的 ruby 內有多少種文字編碼嗎?你會很驚訝:
還好,我們現在幾乎都只有用 UTF-8 了,先來看一下簡單的編碼轉換(...... 一點也不簡單):
寫的真是落落長,因為真的不簡單,不過,要講的重點就是以下幾點而已:
這也說明了 force_encoding 與 encode 的不同。
用 Rails 的人,剛開始不大會碰到 encode 編碼的問題,但是只要網站上線的時間一久,一定會碰到,而且很難抓,因為編碼的轉換不一定會出錯,只有當轉換到的目的碼不存在時,才會出錯,所以,最後一行的 encode 有處理不合法與未定義字元的功能,就很實用了。
如果你的網站都沒有連外,你很幸福,問題不大,只不過太不可能了,除非你是做內網的,只要你的網站能讓外部讀取的,就會有很多很多的機器人來讀你的網頁,這時,你很快就會遇到:
incompatible character encodings: UTF-8 and ASCII-8BIT
嚴格說起來,這真的不是你的問題,也不是 Rails 的問題,都不是,又是一個歷史包袱,我們前面提到了網址一定是 ASCII 編碼,所以只要你的網站有讀取使用閱讀者的網址,恭喜你,這外部的網址在 Rails 中就是 ASCII-8BIT 編碼,如果有人想要知道更詳細,請讀:
rack request environment variables are allways encoded in ascii-8bit regardless of default_external Encoding GitHub
這問題常發生在當你用
request.original_url
讀取你的網站閱讀者要求的網址時,這個編碼是 ASCII-8bit 的,而這個內容與編碼是來自 Rails 得更底層 Rack,事實上,網址就一定是 ASCII 編碼也沒錯,可是只要你一使用它,一段時間後,終會遇到出錯,大部分是來自機器人,他們自己組合了一些編碼造成我們內部轉換成 UTF-8 出錯,常發生的地方就在我們設定 Meta tag 的地方:<meta property="og:url" content="<%= request.original_url %>" />
解法也很簡單,就轉成 UTF-8,如果你不在乎內容正確,就強迫轉吧:
<meta property="og:url" content="<%= request.original_url.force_encoding('utf-8') %>" />
這種錯誤很難抓,我花了兩天才找到,這也是我特別寫在這的原因,希望對大家有幫助。
invalid byte sequence in UTF-8
出現這錯誤時,應該就是有人輸如了不屬於 UTF-8 的合法文字,你如果 debug 進去看,通常就是這種 \xA6a\xC4y\xAEMøӣū\xADp 不合法文字,最簡單的方法就是用 scrub method 刪掉它:
我是還蠻喜歡
str
.scrub('_')
,換成底線!