摘要:如果非要用漢語理解的話應該是一段小型文本文件,由網景的創始人之一的盧蒙特利在年發明。上述的套路會一直用下去,的組合。應該填入信息后,錯誤信息就消失的。
cookie 如果非要用漢語理解的話應該是 一段小型文本文件,由網景的創始人之一的盧 蒙特利在93年發明。實現基本的注冊功能上篇是熟悉一下注冊的大致流程,下篇熟悉登錄流程以及真正的Cookie
我們打開網站,瀏覽網站,最常見的兩個操作就是注冊以及登錄,所以有必要探索一下這兩個功能如何實現的。
本地模擬,當輸入localhost:8080/sign_up的時候,瀏覽器發起get請求,服務器給你響應sign_up.html
//服務器端代碼 if (path === "/sign_up" && method === "GET") { let string = fs.readFileSync("./sign_up.html", "utf8") response.statusCode = 200 response.setHeader("Content-Type", "text/html;charset=utf-8") response.write(string) response.end() }CSS布局的幾個小坑
在寫sign_up.html的時候,注意幾點css知識:
如果想讓你的登錄頁面的body占滿整個屏幕,隨著窗口的大小變化而變化的話,可以寫
body, html{height: 100%} //或者 body{min-height: 100%} html{height: 100%} //不能這么寫 body, html{min-height: 100%}
當然了,實際上這么寫就可以了
body{min-height: 100vh}
label標簽是display: inline,不能設置寬度,行內元素則會根據行內內容自適應寬度,所以行內元素設置width是沒有效果的。改成inline-block就可以了
獲得用戶的數據既然是注冊的需求,那么我們首要關注的點就是--用戶的注冊信息我們如何獲得呢
選擇合理的數據結構存儲數據是很重要的。
每個input的name可以使用數組存儲
input的value應該使用hash,也就是對象來存儲。
上述的套路會一直用下去,hash+[]的組合。
//使用jq來寫 let hash = {} let $form = $("#signUpForm") $form.on("submit", (e) => { e.preventDefault() //不用form表單的默認提交,而是使用我們的的ajax提交 let need = ["email", "password", "password_confirmation"] need.forEach((name) => { let value = $form.find(`[name=${name}]`).val() hash[name] = value })
最終hash里面存儲的就是
{ "email": "...", "password": "...", "password_confirmation": "..." }
到目前為止我們把用戶的數據封裝到了一個對象里面了。
不過在把hash用ajax發出去之前要先進行一些必要的非空驗證
非空驗證主要是檢測郵箱是否為空、密碼是否為空、兩次輸入的密碼是否一致。
//發起請求之前驗證是否為空 if (hash["email"] === "") { $form.find("[name="email"]").siblings(".errors").text("請您輸入郵箱") return false //精髓啊,不然沒用了 } if (hash["password"] === "") { $form.find("[name="password"]").siblings(".errors").text("請您輸入密碼") return false //精髓啊,不然沒用了 } if (hash["password_confirmation"] === "") { $form.find("[name="password_confirmation"]").siblings(".errors").text("請您再次輸入確認密碼") return false //精髓啊,不然沒用了 } if (hash["password"] !== hash["password_confirmation"]) { $form.find("[name="password_confirmation"]").siblings(".errors").text("兩次輸入密碼不匹配") return false //精髓啊,不然沒用了 }
如果忘記寫return的話,即使你為空了還是會直接越過這一步檢測,去發起ajax請求的,所以一定不要忘了寫上return false.
如果僅僅這么寫的話會有一個bug。當出現錯誤提示后,你把信息填對了,錯誤信息依然顯示,這顯然是不合理的。應該填入信息后,錯誤信息就消失的。
$form.find(".errors").each((index, span) => { $(span).text("") })
使用上述的jq代碼來解決這個bug即可。
非空驗證完了之后,意味著瀏覽器收集用戶數據的工作完成了,可以把hash發到服務器端了,接下來就是ajax請求了。
使用ajax提交數據$.post("/sign_up", hash) .then((response) => { //成功了就打印這個 console.log(response) }, () => { //錯誤了打印這個 })服務器端解析formData
因為formData是一段一段上傳的(具體原因略復雜,可以取極限法,如果formdata很多,不可能一下子上傳過來),自己不會寫,就去搜索代碼片段解析formdata
google: node get post data
把獲得的代碼封裝成了一個函數
function readBody(request) { return new Promise((resolve, reject) => { let body = [] request.on("data", (chunk) => { body.push(chunk) }).on("end", () => { body = Buffer.concat(body).toString(); resolve(body) }) } ) }
如何使用上述代碼片段呢
... if (path === "/sign_up" && method === "POST") { readBody(request).then((body) => { let strings = body.split("&") //["email=1", "password=2", "password_confirmmation=3"] let hash = {} strings.forEach(string => { //想得到類似這種的 string == "email=1" let parts = string.split("=") //再用=分割,得到["email", "1"] let key = parts[0] let value = parts[1] hash[key] = decodeURIComponent(value)//hash["email"] = "1" }) let {email, password, password_confirmation} = hash //ES6的解構賦值 } ...
當服務器端接收到了所有的formdata數據后,其實是一串形如email=1&password=2&password_confirmation=3
的字符串,所以我們考慮使用&字符分割成數組。
得到一個形如["email=1", "password=2", "confirmation=3"]的數組之后,我們為了得到string = "email=1"這種形式的,開始遍歷數組,把數組的每個元素按照=分割,得到 [email, 1]
用第二小節提供的hash+[]方法,處理成hash
服務器端簡單的校驗既然服務器端已經獲得了formdata了,那么應該進行一下簡單的校驗,比如郵箱的格式,沒有問題了就把數據存到數據庫里面。(目前校驗水平很入門,沒有涉及到完備的注冊校驗功能)
校驗前的準備工作上一節我們把formdata完美的封裝到了hash里面,為了校驗我們要把hash再拆開一個一個的看
或許這么做是最直接的
let email = hash["emai"] let password = hash["password"] let password_confirmation = hash["password_confirmation"]
不過ES6提供了一種解構賦值的語法糖,很甜很貼心……
let {email, password, password_confirmation} = hash由@編碼引發的bug
好了,我們這一步就先看看郵箱格式是否正確。
我是菜鳥級校驗郵箱,看到了郵箱的獨特標志---@,最起碼有這個標志才叫郵箱吧,也就是說沒有這個標志,我就可以認為郵箱格式不對啊,翻譯成代碼就是
if (email.indexOf("@") === -1) { response.statusCode = 400 response.write("email is bad") //單引號只是為了標記這是一個字符串 }
很好,目前來說,事情的發展都很正常,直到一個bug的到來。
一個合法的郵箱,卻進入了非法郵箱處理的代碼片段里面……
毫無疑問,郵箱是合法的,代碼也是合理的,那么出問題的必然是我,某個地方的理解有問題。
找bug,把可能出錯的代碼片段分成幾個區間,打log.
console.log(email.indexOf("@")) console.log(email)
沒錯,email這個字符串的@索引真的是-1,可是我的郵箱寫的明明有@啊。
為啥呢,接著又打印出了email的內容,終于真相大白了,email字符串里面真的沒有@,
卻發現了一串你沒想到的%40,(⊙v⊙)嗯,沒錯了,這就是我認為的那個@的另一個形態。
我在瀏覽器看到的只是瀏覽器想讓我看到的東西而已,既然已經被瀏覽器處理了,那到了服務器端自然無法處理。
那這個%40哪來的呢
Google走起,在w3schools的HTML URL Encoding Reference找到了解釋(不是國內的w3school……)
URL encoding converts characters into a format that can be transmitted over the Internet.
URL編碼把字符轉化成了一種可以在互聯網上傳播的格式,也就是說,我在網頁上看到的字符是被URL編碼處理的結果。
那接下來就去搞定什么是URL編碼
搞定這個之前,文檔先要讓你明白啥是URL
Web browsers request pages from web servers by using a URL.The URL is the address of a web page, like: https://www.w3schools.com.
Web瀏覽器通過使用URL從Web服務器請求頁面。 該網址是網頁的地址,例如:https://www.w3schools.com。
復習一下URL的組成6部分:
https://www.baidu.com/s?wd=he... 通過這個你就可以訪問到一個 "唯一的" 網址
名字 | 作用 |
---|---|
https: | 協議 |
www.baidu.com | 域名 |
/s | 路徑 |
wd=hello&rsv_spt=1 | 查詢參數 |
#5 | 錨點 |
端口 | 默認80 |
復習完了URL,繼續搞URL編碼
URLs can only be sent over the Internet using the ASCII character-set.Since URLs often contain characters outside the ASCII set, the URL has to be converted into a valid ASCII format.
URL encoding replaces unsafe ASCII characters with a "%" followed by two hexadecimal digits.
URLs cannot contain spaces. URL encoding normally replaces a space with a plus (+) sign or with %20.
URL只能用ASCII編碼在互聯網之間發送。
既然URL通常包括ASCII字符編碼集之外的字符(很明顯嘛,ASCII碼表太少),所以URL必須轉化成有效的ASCII格式。
這是重點,URL編碼使用%后面緊跟著兩個16進制數字的編碼格式來代替不安全的ASCII碼表
URL不能包括空格。所以URL編碼通常使用+號或者20%來代替空格。
繼續往下翻,找到了%40。
所以要把value的值解碼回去
hash[key] = decodeURIComponent(value)
decodeURIComponent() 方法用于解碼由 encodeURIComponent 方法或者其它類似方法編碼的部分統一資源標識符(URI)。畢竟URL屬于URI。
錯誤信息的提示方法如果有了錯,需要提示用戶錯了,后端寫的代碼,用戶不一定看的懂,需要前端潤色一下使用戶看懂,或者前端和后端溝通一下,maybe后端脾氣不好,前端也是暴脾氣,所以應該選擇一個前后端都要用的東西做橋梁,很明顯JSON是完美的候選人。
if (email.indexOf("@") === -1) { response.statusCode = 400 response.setHeader("Content-Type", "application/json;charset=utf-8") //直接告訴瀏覽器我是json response.write(` { "errors": { "email": "invalid" } } `) }
這就合理多了,后臺只管寫個json給前臺看,其他不管了,前臺翻譯一下給用戶看嘍~
那么前臺如何獲得這個json呢
$.post("/sign_up", hash) .then((response) => { //成功了就打印這個 console.log(response) }, (request, b, c) => { console.log(request) console.log(b) console.log(c) })
忘記了錯誤函數里面的參數是啥了,那就都打印出來看看。
可以看到,如果沒用JSON的話,request對象里面有一個后端寫的responseText屬性可以利用。
設置了Content-Type:application/json;charset=utf-8之后,可以利用多出來的responseJSON屬性,獲得json的內容啊。
最終失敗函數里面寫
(request) => { let {errors} = request.responseJSON if (errors.email && errors.email === "invalid") { $form.find("[name="email"]").siblings(".errors").text("您輸入的郵箱錯啦") } }校驗郵箱是否已經存在了
var users = fs.readFileSync("./db/users", "utf8") try { users = JSON.parse(users) //[] JSON也支持數組 } catch (exception) { users = [] } let inUse = false for (let i = 0; i < users.length; i++) { let user = users[i] if (user.email === email) { inUse = true break } } if (inUse) { response.statusCode = 400 response.setHeader("Content-Type", "application/json;charset=utf-8") response.write(` { "errors": { "email": "inUse" } } `) }
本文并沒有使用真正意義上的數據庫,只是使用了簡單的db文件做數據庫,其實就是存的數組,也就是users其實就是數組[]。
之所以使用了try{}catch(){},是因為一旦除了錯,可以將其初始化為空數組,后續代碼可以繼續執行,可能并不嚴謹,不過本文是側重了解注冊的思路的。
同樣的,如果郵箱已經存在了,就提示用戶
if (errors.email && errors.email === "inUse") { $form.find("[name="email"]").siblings(".errors").text("這個郵箱已被注冊啦") }
后端校驗必須很嚴格,因為可以通過curl越過前端的校驗。
把信息寫入數據庫沒有錯誤之后,就可以把信息寫到數據庫里面啦
users.push({email: email, password: password})//是個對象啊 var usersString = JSON.stringify(users) fs.writeFileSync("./db/users", usersString) response.statusCode = 200
users實現是個對象,而對象是內存里面的東西,數據庫里面應該存儲的是字符串,所以用了JSON.stringify(users)
好啦,上篇注冊篇結束啦,下篇講一講如何登錄以及Cookie登場
相關代碼見sign_up.html
server.js
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/107346.html
摘要:例如用戶去去買點東西,添加了一個熱水壺一部小米手機到購物車里面,那么服務器端可以改寫你上面的使之具體化,表示你購物車里面買了倆東西。一張圖總結注冊登錄的過程接下來可以去搞一搞其他的,像什么哇代碼鏈接 上篇介紹了注冊的基本流程,下篇簡單的講講登錄的流程以及Cookie的出現 實現登錄的小功能 當你在瀏覽器的輸入框里輸入localhost:8080/sign_in的時候,會發起GET請求,...
摘要:例如用戶去去買點東西,添加了一個熱水壺一部小米手機到購物車里面,那么服務器端可以改寫你上面的使之具體化,表示你購物車里面買了倆東西。一張圖總結注冊登錄的過程接下來可以去搞一搞其他的,像什么哇代碼鏈接 上篇介紹了注冊的基本流程,下篇簡單的講講登錄的流程以及Cookie的出現 實現登錄的小功能 當你在瀏覽器的輸入框里輸入localhost:8080/sign_in的時候,會發起GET請求,...
閱讀 2809·2021-10-26 09:48
閱讀 1671·2021-09-22 15:22
閱讀 4028·2021-09-22 15:05
閱讀 608·2021-09-06 15:02
閱讀 2607·2019-08-30 15:52
閱讀 2107·2019-08-29 18:38
閱讀 2755·2019-08-28 18:05
閱讀 2332·2019-08-26 13:55