① Koa 學習總結
Koa是基於Node.js的下一代web框架,由Express團隊打造,特點:優雅、簡潔、靈活、體積小。幾乎所有功能都需要通過中間件實現。
即便沒有給ctx.body 設置響應數據,或訪問不存在的路由,頁面也會顯示Not Found,這是koa底層做了處理,不像原生Node或Express一樣頁面會一直處於響應狀態。
Koa將Node的request 和 response對象都封裝到了context中,每次請求都會創建一個ctx,並且在中間件中作為接收器使用。
以下是剛才訪問時的ctx對象
即便使用ctx.res.write()也不會得到預期結果,比如:ctx.res.write('hello'),結果是hellook,會把message的值拼接上。
有關cookie和session單獨介紹用法。
Koa中的路由和Express不同,Express是把路由集成在Express中,Koa則需要通過kao-router模塊使用。
Koa最大的特色和最優的設計就是中間件,就是在匹配路由之前和匹配路由之後執行函數。
使用app.use()載入中間件。每個中間件接收兩個參數,ctx對象和next函數,通過調用next將執行權交給下一個中間件。
中間件分為:
對於諸如js、css、img等靜態資源採用koa-static中間件處理。
比如靜態目錄為static:
在模板中即可訪問:
koa生態的模板引擎挺多的,比如ejs、art-template等。
使用方式和ejs一樣。
性能上相比,art-template比ejs快很多,開發中用的最多的還是art-template。
http是無狀態、無連接的。不會對之前發生過的請求和相應狀態進行管理團物。也就是說,無法根據之前的狀態進行本塌喊液次的請求處理。
比如訪問淘寶首頁並登錄賬號後,當再打開淘寶其他頁面時,因為每一次的訪問都是獨立的,伺服器並不知道你已經登錄,所以還是不能下單或者加購物車之類的操作。
cookie是客戶端第一次訪問伺服器的時候,伺服器在下行HTTP報文時通過響應頭的 set-cookie 欄位給瀏覽器分配的一個具有特殊標識的文本信息,此後當客戶端再次訪問同一域名時,便會將該欄位通過請求頭攜帶到伺服器。注意: 第一次訪問伺服器是不可能攜帶cookie的。
缺陷: 1、cookie的數據存放在客戶端,不安全,容易被(CSRF)跨站請求偽造。攻擊者可以藉助受害者的 Cookie 騙取伺服器的信任,可以在受害者毫不知情的情況下以受害者名義偽造請求發送給受攻擊伺服器,從而在並未授權的情況下執行在許可權保護之下的操作。2、單個cookie保存的數據不能超過4K,很多瀏覽器都限制一個站點最多保存20個cookie。
通過 options 獲取 cookie name:
通過 options 設置 cookie name 的 value:
通過buffer轉成base64存進去,取出來是再轉回中文。
session是另一種記錄客戶狀態的機制,不同的是cookie保存在客戶端瀏覽器中,而session保存在伺服器上。
前面說過,cookie 是存放在客戶端,不是很安全,用戶可以自己手動把cookie種在客戶端以欺騙伺服器。而session是存儲在服務滲櫻端的,所以對於較重要的數據存儲在session。
缺點: session會在一定時間內保存在伺服器上。當訪問增多,會比較佔用你伺服器的性能。
當瀏覽器第一次請求伺服器時,伺服器端會創建一個session對象,生成一個類似於key-value的鍵值對, 然後將key(cookie)下發到客戶端,當客戶端再訪問時,攜帶key(cookie),找到對應的session(value)。 生產中用戶的信息都保存在session中。
以上配置選項常用的就是key、maxAge、httpOver。
renew應用:比如我們登錄賬號寫一篇博客,寫了一半cookie過期了,當我們提交的時候就會退出登錄,體驗很不好,而且寫好的博客丟失。
301和302重定向狀態碼區別。302為臨時重定向,301永久重定向。Koa中默認為302。詳細信息查看這篇博客 301和302重定向介紹
字元串 「back」 是特別提供Referrer支持的,當Referrer不存在時,使用 alt 或「/」。
要更改 「302」 的默認狀態,只需在該調用之前或之後分配狀態。要變更主體請在此調用之後:
解決跨域的方式有很多種,個人認為最好的方案是在伺服器端設置支持跨域。
下面詳細說明在koa2中設置具體的請求頭信息:
在koa2中,解決跨域請求還可使用中間件 koa2-cors
node 發送郵件可以使用 nodemailer 三方模塊。
安裝:
使用說明:
更多詳細配置信息及功能參照 官網
② koa開啟cors允許跨域,攜帶cookies
使用koa開發想要開啟 cors 非常簡單,已經有對應的庫: @koa/cors 。
雖然庫的readme沒有具體介紹具體的用法,但是我們可以通過閱讀測試用例知道可以傳什麼參數,什麼類型。
只需要兩行,介面就會在返回數據的時候帶上 Access-Control-Allow-Origin 響應頭。默認允許所有請求方式跨域, Access-Control-Allow-Origin 默認為 * 。
為了安全考慮,攜帶cookies的跨域請求只允許 Access-Control-Allow-Origin 為單一域名,即只支持一個域名在請求的時候攜帶cookies。且需要帶上響應頭 Access-Control-Allow-Credentials
對 @koa/cors 添加配置 origin 和 credentials :
同時,前端要發起攜帶cookies的跨域請求,需要設置 XMLHttpRequest 的 withCredentials 為 true ,如果你是使用 axios ,只需要在請求配置里加上一句 withCredentials: true ,請看例子:
這樣前端( http://koa.com )就可以向後端( http://localhost:8000 )發送請求了。
如果你的前端地址只有一個,給 @koa/cors 的 origin 添加一個域名就能滿足需求,如果需要支持跨域的域名有多個呢?
通過觀察 @koa/cors 的 單元測試用例 ,可以發現 origin 是支持用函數的方式傳入的。這樣我們就可以維護一個域名數組,判斷請求地址是否在域名數組內,就能知道是否要對請求地址提供攜帶cookies請求支持了。
要想知道發起請求的前端地址,可以使用 ctx.request.header.origin 。注意 ctx.request.header.origin 和 ctx.request.origin 是不同的。 ctx.request.origin 是介面域名, ctx.request.header.origin 是發起請求的頁面域名。