2018年8月10日 星期五

Web Front-End 菜鳥筆記:如何讓瀏覽器記住 form input field 的值(p.s. Chrome 的不合群行為還沒解開)

人生中第一份前端工程的全職滿三個月了~公司還沒倒(灑花)

這幾天解一個看起來簡單的小 issue,就是讓 browser 可以 autofill / autocomplete 登入表單中的欄位,結果意外的卡了超久 XDrz

目前在 Firefox / Safari 可以正常運作,但在 Chrome 則是時靈時不靈。先簡單筆記一下給將來的自己參考,順便看看有沒有過路神明會開示一下

如何讓瀏覽器記住 input field 的值


有兩種方式

1. 由使用者自行利用瀏覽器內建的 autofill 功能
2. 由開發者撰寫會觸發 form submit 事件的 html elements

參考:Autofill: What web devs should know, but don’t - Cloud Four


開發者視角——如何利用 form submit 事件達成 autofill


觸發 form submit 事件的前提包括:

1. <input> 有設定 name 屬性

因為瀏覽器是認 name 來記憶欄位的內容。

2. <input><form>autocomplete attribute 未設定為 off

預設是 on 所以只要不要特別設定成 off 就可以了。
參考:How to Turn Off Form Autocompletion - Web security | MDN

3. 送出資料的 <input><button> 有設定 type="submit" 屬性

而且要包在 <form> 裡面,因為 submit 事件是綁在 <form> 身上的。
參考:submit - Event reference | MDN

4. submit 事件沒有被 preventDefault() 阻擋

如果有擋的話,擋完要自己手動 submit()
參考:Answer: Submit form using preventDefault() but keeping browser autocomplete feature
參考:HTMLFormElement.submit() - Web APIs | MDN

5. 送出的資料有通過 <form> 本身的 validation

不然 submit 事件會被 browser 自己擋下來。


form submit 事件有成功觸發的話,browser 會跳出小視窗,問使用者要不要記住剛才輸入的帳號密碼。

Chrome 的問題


做完上面的東西後,東測西測,發現我的 Chrome 只有在

1. 每次 refresh 後的第二次 submit 時
2. 無效 submit 後按 refresh 時

才會觸發瀏覽器內建的 autofill 功能,也就是 Google Smart Lock 的彈出視窗。但同樣的 code 跑在 Firefox 跟 Safari 上,每次按 submit 都能夠正確觸發更新 autofill 的彈出視窗。

爬 google 老半天後才發現這好像是 Chrome 一直以來的問題...

2010 年:Form submit not working with Chrome - Google Product Forums
2016 年:javascript - Chrome Autofill/Autocomplete no value for password - Stack Overflow

連結中寫的一些 workaround 作法,因為小蝦腦容量不足沒打算解到這麼細所以目前還沒深究,哪天有實做上的結論再回來更新本文。

其他


1. 一些 <input> 可以使用的 autocomplete 屬性的值

參考:HTML Standard - Living Standard — Last Updated 9 August 2018

2. 兩種觸發 form submit 事件的方式:enter 鍵 v.s. submit 按鈕

參考:Form submission: event and method submit

3. 在不使用 preventDefault() 前提下避免瀏覽器在 form submit 後預設的 redirect 行為

簡單來說就是開一個隱形的 <iframe>,把它設定成 form 的 target。
參考:javascript - Trigger autocomplete without submitting a form - Stack Overflow

4. 順便逛到的, preventDefault()return false 的比較

參考:javascript - event.preventDefault() vs. return false - Stack Overflow

結論


奉勸各位施主不要因為人家 issues 標記為 low priority 就以為很簡單,然後貿然拿來當做零碎時間塞塞牙縫調劑身心的小遊戲什麼的,畢竟,人衰起來的時候勢如破竹,什麼都擋不住~~~