從登入框看前端

發表於2014-01-24

我們會罵 12306 的網站介面挫,效果差,速度慢,回頭看看自己寫的程式碼,是不是也一樣的狗血!在前端,很多看似簡單的東西,內藏無數玄機。本文將以一個小小的登陸框為入口,談一談如何完善自己的程式。

在很多人眼裡,前端就是 DIV+CSS+JQuery,甚至還有些人停留在 table 佈局的迷霧當中(這些人應該跟 IE6 一樣,隨著歷史漸漸被塵封)。但,前端絕不是你所看到的那樣。舉個例子,登入頁面幾乎是每一個系統不可或缺的模組,很多嫻熟的人可以在一刻鐘之內寫好一個登入頁面,兩個 input,一個提交 button,萬事 OK。

當然,作為一個完成登入驗證的頁面,這幾個元素完全可以勝任,但我只能說你完成了一個可以用的頁面,這種頁面完全沒有使用者體驗可言,完全不符合一個具有的嚴謹的思維的程式設計師的作風!

一、一切以良好使用者體驗為基礎

1. 視覺效果

介面的設計就不用多說了,一般情況這個屬於美工的活兒,這裡要談的是幾個最基礎的點。

第一,你的頁面相容性如何?各個元素的長寬、行高等在不同瀏覽器上是否表現一致,如果這個都沒有保證,那一定是不合格的。

第二,移動終端上的體驗問題,如今很多頁面 PC 和移動終端都用的一套結構,也就是我們所說的響應式佈局,本部落格就使用了響應式佈局,縮小視窗可以看到效果,響應式佈局是為了讓不同的移動終端也能得到同樣的優質體驗,可是很多開發者卻忽略了橫屏時的效果。下面是常見的幾個移動終端的畫素比例:

Mobile px rate
Iphone5 320*568
Iphone4 320*480
Galaxy S 3/4 360*640
Lumia 920 384*640
iPad 768*1024

照顧使用者的響應式佈局除了要考慮這些螢幕的橫屏,還得把豎屏考慮進去。我簡單的做了一個登陸頁面:

fdhfghfhj131712295330

正確的賬號是:barret,密碼是:123,你可以用錯誤的資訊先去測試下~

可以戳這個DEMO:http://qianduannotes.duapp.com/demo/login/login.html

2. 互動

前面那種方式,點選提交按鈕,送到後臺去驗證,驗證沒有通過則回到登入頁面,這也算是一種互動,不過這種互動的體驗是特別不好的,每次都得重新重新整理頁面,應該利用 ajax 非同步去驗證表單。為了省去使用者的聚焦點選,可以按照下面的思路來做:

  1. 使用者名稱為空,或者格式不對 -》 提示錯誤,清空密碼框,聚焦到使用者名稱框,並全選使用者名稱
  2. 使用者名稱不存在 -》同上
  3. 密碼錯誤 -》 提示錯誤,清空密碼框,聚焦密碼框
  4. 聚焦到密碼框,全選密碼

告訴使用者哪個地方出了問題,並提前預知使用者遇到這些問題之後會做哪些事情,我們能夠用程式解決的事情,絕不麻煩使用者親自動手操作。當提示使用者名稱錯誤的時候,使用者肯定會回到輸入框重新輸入,這個時候我們已經聚焦到使用者框,並全選了之前的輸入,方面使用者進行刪除操作。類似這樣的互動,我們應該提前做預判斷。

3. 狀態提示

什麼是狀態提示?有時候因為網路原因,點選提交 button 之後,ajax 傳輸半天沒有響應,使用者等了半天頁面一點提示都沒有,這個肯定會讓使用者焦急的。回頭看看 Gmail,一個把 ajax 發揮到極致的 web應用,在使用者體驗上做的也是相當給力的,登入郵箱的時候一個 loading 動畫,旁邊還放了一個載入基本HTML(供慢速網路使用),每一個操作都有提示,提示中還有一個撤銷操作的按鈕,資料進行載入的時候,如果載入時間過長,期間會進行多次不同的提示,並在最後給出一個確切的結果,對於一個登陸框而言,需要做到這些:

  1. 一個明確的用於狀態提示的 box
  2. 等待 3s,結果沒有出來,提示使用者繼續等待
  3. 等待 6s,結果沒有出來,提示使用者網路不暢通
  4. 設定 10s 為超時,並告知使用者提交表單失敗

這些東西的實現並沒有太多的技術難度,但是可以給慢速網路下的使用者帶來很好的體驗和安全感。

4. 安全傳輸

使用者最擔心的是賬號密碼被截獲,或者因為密碼一處多用,不希望別人看到密碼的明文,既然使用者擔心,我們就應該想辦法來處理。

把密碼和時間戳疊加,然後加密,傳到後臺的是加密的結果以及這個時間戳,如下:

這樣就可以保證密碼的隱蔽性,如果 hacker 不知道 decode 函式,即便是拿到了 s 和 t,也是徒勞。關於安全傳輸,之前也寫過相關的文章,OAuth認證原理及HTTP下的密碼安全傳輸。如果要做到在使用者輸入的時候就絕對安全,那就必須使用類似 支付寶安全外掛 這樣的東西了。他的原理就是在頁面中嵌入一個控制元件,這個控制元件與頁面之間是相互遮蔽的,在控制元件內部輸入也只有控制元件拿得到輸入資訊。

5. 資料走快取

表單提交首選應該是 post,但是也不排除會用 get 方式提交,那麼這個時候就應該考慮資料快取了,如果請求的 url 相同,程式就會直接從瀏覽器的快取中拿資料,並給出狀態是 status: 200 OK(from cache),為了避免這些常識性的問題,記得在請求的引數中加點東西。

為了保證引數的絕對唯一性,甚至可以把 時間戳 和隨機數疊加起來用

6. 漸進增強

漸進增強這個詞一般是,不支援 javascript 或者對 javascript 支援度不太好的瀏覽器上利用其它方式實現,或者告訴使用者什麼原因不能用,就是一種蛻化處理。目前不支援 javascript 的瀏覽器應該是絕跡了,當然也不是絕對,kindle 內建的瀏覽器對 javascript 的支援度就不高,或者根本就不支援。還有一種情況是使用者禁用了 javascript,這個比例很小,開發者會這麼幹,一般的使用者不會亂改瀏覽器設定。但是我們的程式,尤其是關鍵的部位(如搜尋,登入,註冊等)必須要考慮這一少部分群體。一般採用的方式是:

1)使用 noscript 標籤,這個是最常用,也是最實用的。

2)hack 方式,document.write(“<” + “!–“)

這是一種特別巧妙的處理手段,也是值得推薦的。

7. 瀏覽器後退按鈕

這個在註冊或者登陸的時候是一個普遍的問題,登陸之後,跳轉到另外一個頁面,我的滑鼠有兩個側鍵,是用於前進和後退的,有時候會誤點側鍵,這個時候頁面又會回到之前的登入頁面,但事實是使用者已經登入了,所有頁面的狀態都應該是已登入的,不管什麼情況下都不應該讓使用者在看到這個頁面。使用者的點選操作會引發上面的問題,而程式 history.go(-1) & history.back() 也會有一樣的bug。

這樣的問題處理方案比較簡單,ajax 拿到 success 的狀態碼時立刻做跳轉,但是這裡不能用 window.location.href,這樣瀏覽器還是會記錄這個登入歷史,應該使用 window.location.replace,替換當前歷史記錄。

8. 記住密碼

使用者最煩的就是每次登入頁面都要輸入長長的賬號密碼,如果沒有勾選“記住密碼”,則使用者的登入狀態儲存在回話的 session 中,關閉頁面或者瀏覽器的時候,回話結束,session 被刪除,這樣當使用者下次登入的時候又需要重新輸入密碼。表單頁面的“記住密碼”核取方塊預設狀態應該是已選擇,使用者的潛意識行為都是要少操作的。

當使用者提交資訊成功之後,直接在 cookie 中儲存賬號密碼?這樣的做法顯然是不合理的,密碼怎麼能夠明文儲存呢,有人會想到加密處理密碼然後再儲存,或者使用伺服器來設定 cookie,這些做法都是可以的,不過最好的方式是,當使用者成功提交資訊時,伺服器給前端提供一個 token,這個 token 是用於自動登入的,我們只需要儲存 token 就行了,這樣就很好的避免了 cookie 中存放使用者隱私資訊了。

還有一個要注意的是,當使用者取消了“記住密碼”的核取方塊時,應該立即清除相關 cookie。

二、其他相關的幾個點

1. 使用者忘記密碼

如果使用者很長時間沒有來你的網站,他可能會忘記自己設定的密碼,一些奇葩的使用者甚至會忘記自己的使用者名稱,但是使用者永遠是沒有錯的,出錯的只有我們的程式和寫程式的人。對於忘記密碼的人,可以在填寫密碼的旁邊加上一個連結 “忘記密碼?”,讓使用者利用郵箱或者繫結的手機來找到密碼,對於忘記密碼以及使用者名稱的人,內傷中… @undefined 13# 14# 正解

2. 指令碼注入

表單資訊應該做正則匹配,或者資訊的過濾,防止指令碼注入,這個主要是後臺要考慮的問題,就不多說了。

3. 多次提交

我們發微博的時候經常會遇到的問題,因為網路原因,會多次點選發布按鈕,這個問題有多種處理方案:

  • 釋出之前先從伺服器拿 token,該 token 只有一次有效
  • 後端判斷一定時間內使用者釋出的多條資訊,相同的資訊去重

三、容易出錯的幾個知識點

1. setRequestHeader

利用 ajax 來 post 資訊,有的人可能遇到過,後臺拿不到資料。原因是沒有重寫 請求頭的 Content-Type,

一般瀏覽器不支援 GET 方式時 xhr.send 中新增引數,但是 POST 是可以,也是必須的,如果沒有設定 Content-Type 的頭部,資料送到後端便沒辦法解析成 key-value 的模式,後臺(PHP)通過 $_POST 也拿不到資料。

2. checkbox

這裡也是一個體驗問題,一些人把 checkbox 和他相關的文字分開寫,結果沒有使用 label 來指向,如:

很顯然,我們點選後面的文字是不會讓 input 改變狀態的,有些人會這麼處理:

這樣處理之後,點選文字當然可以選中 input,但是這種處理方式是不合理的,label 本來就是標記 input 框用的,他的內容應該是文字,不應該包含 input 這個框,所以合理的做法應該是這樣:

四、小結

上面說了一大堆,很多問題都是站在使用者的角度去思考的,我們是程式設計師,但是我們也是使用者,我們會吐槽,但是我們也會被吐槽。

把使用者體驗做到極致,這個十分重要,不要放過任何一個細節!

相關文章