差異處

這裏顯示兩個版本的差異處。

連向這個比對檢視

Both sides previous revision 前次修改
下次修改
前次修改
java:web:wicket:dont_autocomplete [2018/11/09 00:01]
tony [Fake blank input field]
java:web:wicket:dont_autocomplete [2023/06/25 09:48] (目前版本)
行 1: 行 1:
-====== Wicket - Don't autocomplete(Working) ​======+{{tag>​wicket autocomplete password}} 
 +====== Wicket - Don't autocomplete ======
 ===== Problem ===== ===== Problem =====
 瀏覽器的貼心有時會為開發人員帶來困擾:​\\ 瀏覽器的貼心有時會為開發人員帶來困擾:​\\
行 8: 行 9:
 \\ \\
 假如我根本不需要使用帳號密碼,你幫我填入我不是還要自己消掉嗎?​ 除此之外,在Submit後所跳出的對話盒,是另一個困擾。本篇文章會分享針對這兩個問題的治療經驗。 假如我根本不需要使用帳號密碼,你幫我填入我不是還要自己消掉嗎?​ 除此之外,在Submit後所跳出的對話盒,是另一個困擾。本篇文章會分享針對這兩個問題的治療經驗。
-===== How to? =====+===== How to prevent the autocomplete? =====
 我撰寫此篇文章時,測試的瀏覽器分別為以下版本:​ 我撰寫此篇文章時,測試的瀏覽器分別為以下版本:​
-  * chrome: 70.0.3538.77 +  * Chrome: 70.0.3538.77 
-  * firefox: 63.0.1 +  * Firefox: 63.0.1 
-  * ie: 11.0.9600.19129+  * IE: 11.0.9600.19129
 分享的方法是給大家參考,最後要使用哪種就看應用程式需求。 分享的方法是給大家參考,最後要使用哪種就看應用程式需求。
 ==== Don't use type="​password"​ ==== ==== Don't use type="​password"​ ====
行 20: 行 21:
 <code html> <code html>
 <input type="​password" ​ readonly <input type="​password" ​ readonly
-     ​onfocus="​this.removeAttribute('​readonly'​);​this.select();​ this.selectionStart = this.selectionEnd = this.value.length;"/>​+     ​onfocus="​this.removeAttribute('​readonly'​);​this.select();​ this.selectionStart = this.selectionEnd = this.value.length;"​ 
 +     ​onblur="​this.setAttribute('​readonly','​readonly'​);"​  
 +    ​/>
 </​code>​ </​code>​
-在IE上如果僅移除readonly屬性,會造成點擊兩次才能夠輸入密碼的問題。因為我們使用Apache Wicket,使用這種方式比較容易做成可重複使用的元件。+在IE上如果僅移除readonly屬性,會造成點擊兩次才能夠輸入密碼的問題,必須透過再次選取與調整游標位置去讓使用者無痛;onblur是了避免使用者按tab又觸發autocomplete的問題。最後我們使用這方法主要是由於我們使用Apache Wicket,這種方式比較容易做成可重複使用的元件。
 ==== Apply autocomplete="​nope"​ or autocomplete="​off"​ ==== ==== Apply autocomplete="​nope"​ or autocomplete="​off"​ ====
 這方法不推薦使用。目前我知道autocomplete="​off"​可以使用於IE,但autocomplete="​nope"​只能用於chrome與firefox的某些版本。 這方法不推薦使用。目前我知道autocomplete="​off"​可以使用於IE,但autocomplete="​nope"​只能用於chrome與firefox的某些版本。
 ==== Fake blank input field ==== ==== Fake blank input field ====
 這個做法是在form的前面塞入隱藏的欄位給瀏覽器做自動完成。最早我們使用這個方法,但它有以下缺點:​ 這個做法是在form的前面塞入隱藏的欄位給瀏覽器做自動完成。最早我們使用這個方法,但它有以下缺點:​
-  - 如果整合的系統相當多,你會產生許多duplicate ​code。+  - 如果整合的系統相當多,你會產生許多duplicated ​code。
   - 在form submit之後,如果你的real-username與瀏覽器記住的username不同,所彈出記住登入資訊的帳號,會讓使用者覺得這是個bug。   - 在form submit之後,如果你的real-username與瀏覽器記住的username不同,所彈出記住登入資訊的帳號,會讓使用者覺得這是個bug。
   - 在firexo 63以後的版本依然會有自動完成的現象;也是這個原因導致我們花時間研究這個問題。   - 在firexo 63以後的版本依然會有自動完成的現象;也是這個原因導致我們花時間研究這個問題。
行 40: 行 43:
 </​code>​ </​code>​
 (範例程式出自於[[https://​gist.github.com/​runspired/​b9fdf1fa74fc9fb4554418dea35718fe|link]]) (範例程式出自於[[https://​gist.github.com/​runspired/​b9fdf1fa74fc9fb4554418dea35718fe|link]])
 +===== How to prevent the browser show remember login dialog? =====
 +這個問題除了避免使用password欄位以外,目前我沒有萬全之策。以下是我針對不同瀏覽器所觀察到的情況,版本與autocomplete部分相同:​
 +  * IE: 宣告autocomplete="​off"​後就解決了。
 +  * Firefox: 以Ajax Request取代傳統form的submit。
 +  * Chrome: 即使以Ajax Request取代傳統form的submit一樣會出現。目前發現只要在http、可信任的https,且在帳號密碼欄位消失時,才會跳出來;帳號密碼欄位消失指的像是關閉Dialog的動作。
 +以我們的軟體而言,最大問題是在Firefox上。這邊提供個範例給大家參考,如何做form的ajax submit,首先是html部分:​
 +<code html>
 +<form id="​form"​ name="​form">​
 +<input id="​user"​ name="​user"​ type="​text"​ />
 +<input id="​passwd"​ name="​passwd"​ type="​password"​ />​  ​
 +<input id="​btn"​ type="​button"​ value="​shit"/>​
 +</​form>​
 +</​code>​
 +javascript部分,以JQuery為範例,我使用FormData物件來將內容轉為multipart的格式送往server:​
 +<code javascript>​
 +$( document ).ready(function() {
 + $('#​btn'​).click(function(){
 + console.log('​submit form'​);​
 + $("#​form"​).submit();​
 + });
 +
 + $("#​form"​).submit(function(e){
 + var form = $(this);
 + var formData = new FormData(form[0]);​
 + $.ajax({
 + type: "​POST",​
 + url: '​shit.php',​
 + processData:​ false,
 + contentType:​ false,
 + data: formData, ​
 + success: function(data)
 + {
 + console.log(data);​ // show response from the php script.
 + }
 + });
 + e.preventDefault();​
 + });
 +
 +
 +});
 +</​code>​
 +以純javascript而言,使用以上方式就可以避免在firefox上跳出remember login dialog,但是在Apache Wicket 6上就沒這麼樂觀。下圖是我們在使用Wicket Form物件,並將multiple設為true後,發ajax request後的結果:​\\
 +{{:​java:​web:​wicket:​wicket_submit_multiple_form.png|}}\\
 +可以發現它並不是一個ajax request;追根究底到wicket-ajax-jquery.js中的submitMultipartForm,可以發現Wicket是使用iframe來模擬如ajax的request。從Wicket的[[https://​github.com/​apache/​wicket/​pull/​255|Pull Request]]中可以得知,Wicket為了要相容於IE7~IE9,在舊版本的Wicket並沒使用FormData。如果要解決這個問題,有兩個方式:​
 +  * 更新到Wicket8,它在[WICKET-6517]中使用真的Ajax取代了iframe。
 +  * override submitMultipartForm。
 +第二個方法大概這樣做:​
 +<code javascript>​
 +Wicket.Ajax.Call.prototype.submitMultipartForm = function(aContext){
 + var attrs = aContext.attrs;​
 +        // ... do ajax request
 +};
 +</​code>​
 +內容實做,可以參考[[https://​github.com/​apache/​wicket/​blob/​master/​wicket-core/​src/​main/​java/​org/​apache/​wicket/​ajax/​res/​js/​wicket-ajax-jquery.js|wicket-ajax-jquery.js]]內的doAjax,資料從aContext都可以拿到。\\
 +\\
 +如果真的要完全解決這問題,請別使用password。
 +===== 後記 =====
 +之前曾寫過類似文章,方法與前面提到的類似,本篇文章更為完整。
 +  * [[java:​web:​browserAutocomplete|Autocompletion problem on Firefox or Chrome]]
 ===== Reference ===== ===== Reference =====
   * [[https://​jsfiddle.net/​449Lamue/​6/​|demo - 使用text模擬password]]   * [[https://​jsfiddle.net/​449Lamue/​6/​|demo - 使用text模擬password]]
行 46: 行 108:
   * [[https://​gist.github.com/​runspired/​b9fdf1fa74fc9fb4554418dea35718fe|Apply hidden fields]]   * [[https://​gist.github.com/​runspired/​b9fdf1fa74fc9fb4554418dea35718fe|Apply hidden fields]]
   * [[https://​stackoverflow.com/​questions/​17719174/​autocomplete-off-is-not-working-when-the-input-type-is-password-and-make-the|autocomplete ='​off'​ is not working when the input type is password and make the input field above it to enable autocomplete]]   * [[https://​stackoverflow.com/​questions/​17719174/​autocomplete-off-is-not-working-when-the-input-type-is-password-and-make-the|autocomplete ='​off'​ is not working when the input type is password and make the input field above it to enable autocomplete]]
 +  * [[https://​www.jianshu.com/​p/​46e6e03a0d53|通过jQuery Ajax使用FormData对象上传文件]]
 +  * [[https://​github.com/​apache/​wicket/​pull/​255|Allow multipart submission of non modified FormData with Wicket.Ajax]]
 +  * [[https://​wicket.apache.org/​news/​2018/​02/​17/​wicket-8.0.0-M9-released.html|Apache Wicket 8.0.0-M9 released]]
 +  * [[https://​github.com/​apache/​wicket/​blob/​master/​wicket-core/​src/​main/​java/​org/​apache/​wicket/​ajax/​res/​js/​wicket-ajax-jquery.js|github - wicket-ajax-jquery.js]] ​
 +
 +====== ​ ======
 +----
 +\\
 +~~DISQUS~~