--- tags: Node.js 直播班 - 2022 春季班 --- # Node.js 直播班每日任務 第一週 --- - 4/8 每日任務 Day1:[非同步概念、建立 Promise](https://hackmd.io/AMXBRw3jR22p9NC0a4jItA) - 4/11 每日任務 Day2:[非同步概念、使用 Promise](https://hackmd.io/OJDzSoL7R-6JdRbHCRKZPQ) - 4/12 每日任務 Day3:[MongoDB 基本操作: 新增、查詢](https://hackmd.io/TgtMJ7rVSzqVkua1gZu_DQ) - 4/13 每日任務 Day4:[MongoDB 基本操作: 修改、刪除](https://hackmd.io/P7NQzc9uSX2syvol-56mBQ) - 4/14 每日任務 Day5:[非同步概念、async await](https://hackmd.io/iiQw7hA3TUOzm-eZPewUgg) 第二週 --- - 4/15 每日任務 Day6:[schema、mongoose](https://hackmd.io/MGSN1-xOSBWvFx2FSMYVAg) - 4/18 每日任務 Day7:[model、Mongoose 新增 / 查詢](https://hackmd.io/lX0yu-6KRD2rdX-K0cQnCA) - 4/19 每日任務 Day8:[schema 補充](https://hackmd.io/T8aLkLT6SjiEh_dQLrxl2w) - 4/20 每日任務 Day9:[Mongoose 修改 / 刪除](https://hackmd.io/B8e884-cSK6zYsgb7FOIUg) - 4/21 每日任務 Day10:[拆分 Model](https://hackmd.io/dM6fOkJgQe-9-ixsWmKqhg) 第三週 --- - 4/22 每日任務 Day11:[Express 安裝](https://hackmd.io/8NCCRsluSFSSaJct8Kbn8A) - 4/25 每日任務 Day12:[設計基本路由](https://hackmd.io/4xtwDtcwTr6yv6m-WGMnTw) - 4/26 每日任務 Day13:[express 應用程式產生器、在 routes 設計路由](https://hackmd.io/H9FOdWreRGeT8uy3yYDhHA) - 4/27 每日任務 Day14:[req.query 篩選網址參數](https://hackmd.io/EQ3Po0mDRS-V91wf8zlBBg) - 4/28 每日任務 Day15:[req.body 新增資料](https://hackmd.io/tFqX3zZTSq-pazcm7N_Lbw) 第四週 --- - 4/29 每日任務 Day16:[req.params 取得特定資料](https://hackmd.io/wq0Y4d2zTOWdzUIklRHl6Q) - 5/2 每日任務 Day17:[學習時間、方法、進度 分享](https://hackmd.io/gxbAZF8DSwWaR7fNpofn7Q) - 5/3 每日任務 Day18:[Mongoose - Populate](https://hackmd.io/gOkRAVKcSWu0tUz5mVcGSA) - 5/4 每日任務 Day19:[取得資料搭配 sort()、limit()](https://hackmd.io/vprxhH04TR-ASFXgAHIaAQ) - 5/5 每日任務 Day20:[Middleware](https://hackmd.io/Yp0a--8xRwW9LAezQaam-A) <!-- * 4/25:[設計基本路由,可依照最終作業設計稿的頁數來設計](https://expressjs.com/zh-tw/starter/basic-routing.html) * 4/26:[express 產生器(選擇 no view ,因為我們沒有 view 只回傳 JSON),並設計新 router,/user/,新增與修改個人資料](https://expressjs.com/zh-tw/starter/generator.html) * 4/27:練習 req.query 篩選網址參數資料教學 * 4/28:依照 Adobe XD 設計稿,透過 POST API 的 req.body 新增一則貼文,可提供 GitHub 寫一半的範本,並讓他們提交 GitHub Repo,並同時可寫說,請他們要做欄位資料驗證 --> <!-- * 4/29:使用 req.params 取得 :id,例如當對方輸入這個[網址](https://www.facebook.com/sfismy/posts/5281803261839276)時,可以 response 該特定貼文資料,這必須整合 mongoose * 5/2:輕鬆一下,分享平常都何時在練習,簽到目前都在第幾關、需要可以做到什麼程度 * 5/3:(做成像是語法填空),練習 populate 設計一個情境,書本與作者的 collection,然後顯示單一書本的內容時,可以 populate user 的資料 * 5/4:練習 find() 以後,去接 sort 的時間排序、limit 限制幾筆資料 * 5/5:講解 middleware (會釋出影音課程) --> 第五週 --- - 5/6 每日任務 Day21:[HTTP 狀態碼](https://hackmd.io/pe9-iKTxRti2TKXpE7NyoA) - 5/9 每日任務 Day22:[uncaughtException、unhandledRejection](https://hackmd.io/xmSNXfGbQdOTniA_fpS0Yg) - 5/10 每日任務 Day23:[自訂錯誤訊息](https://hackmd.io/cJyEKvpeTfKJ6dcF3K9sNA) - 5/11 每日任務 Day24:[development 及 production 環境變數指令、客製錯誤訊息](https://hackmd.io/FSs4tjRtQqy8jnXnfcLdCw) - 5/12 每日任務 Day25:[非同步錯誤管理](https://hackmd.io/4p9tSRDcTtGVc6Ya0pbBzA) <!-- * 5/6:出選擇題,提供幾個情境,詢問 [HTTP 狀態碼](https://developer.mozilla.org/zh-TW/docs/Web/HTTP/Status)該回傳 200、201、400、401、404、500 等等 - 講解 [handleErrorAsync](https://github.com/hexschool/mongoose-post/blob/main/week5-midtermExam/utils/handleErrorAsync.js),題目:將 handleErrorAsync 加入 [router](https://github.com/hexschool/mongoose-post/blob/main/week5-midtermExam/routes/posts.js#L8-L27) - [appError](https://github.com/hexschool/mongoose-post/blob/main/week5-midtermExam/utils/appError.js) 介紹,在 controllers 加入可預期錯誤 - 設定環境變數執行指令分出 development、production 模式,題目:嘗試客製化兩者模式的回饋訊息 ```javascript // error handler app.use(function(err, req, res, next) { err.statusCode = err.statusCode || 500; err.status = err.status || 'error'; if (process.env.NODE_ENV === 'dev') { console.log('dev'); resErrorDev(err, res); } else if (process.env.NODE_ENV === 'prod') { if(err.isAxiosError== true){ err.message = "axios 連線錯誤"; err.isOperational = true; return resErrorProd(err, res) }else if (err.name === 'ValidationError'){ // mongoose 資料辨識錯誤 err.isOperational = true; return resErrorProd(err, res) } resErrorProd(err, res) } }); ``` - node.js uncaughtException、unhandledRejection 介紹,將有程式錯誤的 app.js 加上 uncaughtException、unhandledRejection,執行時須正確觸發錯誤 --> 第六週 --- - 5/13 每日任務 Day26:[bcrypt.js 密碼加解密](https://hackmd.io/67Pf-ihEQ-SbsHAz0sYvEA) - 5/16 每日任務 Day27:[validator 驗證](https://hackmd.io/9daPlLQWQ1iAoTptHTekgA) - 5/17 每日任務 Day28:[JWT 產生身份驗證 token](https://hackmd.io/nV3gymAVTvuqYECcQTU-wg) - 5/18 每日任務 Day29:[登入功能](https://hackmd.io/TsgmHgmzRfWqT048hRHMEg) - 5/19 每日任務 Day30:[JWT 驗證](https://hackmd.io/gC52vOSmRz2_BtW0i-RzBA) - 5/20 每日任務 Day31:[JWT 驗證 middleware](https://hackmd.io/jZz5qcDLQb2wJ36hEA0v0A) - 5/23 每日任務 Day32:[實作重設密碼](https://hackmd.io/BYirgWM9QRqLK24cmP6agQ) 第七週 --- - 5/24 每日任務 Day33:[multer 處理上傳檔案](https://hackmd.io/yZB0FMW8SxiF0XlTaGMmxg) - 5/25 每日任務 Day34:[Imgur 串接](https://hackmd.io/7BaSIlheSi-8SyKjAF0R3w) 第八週 --- - 5/26 每日任務 Day35:[取得按讚貼文列表](https://hackmd.io/s8p9adD9SqitPqomeIEJtg) - 5/27 每日任務 Day36:[新增、取消特定貼文讚](https://hackmd.io/SlgH_tFDQjuHuhzp2NtUYg) - 5/30 每日任務 Day37:[資料庫設計 embedded / references](https://hackmd.io/Kb-eM0ILQw2g55HoYPjnBQ) - 5/31 每日任務 Day38:[常見資料庫設計](https://hackmd.io/5OrfXagqSf6abjcJetx4DQ) - 6/1 每日任務 Day39:[追蹤 / 取消追蹤使用者功能](https://hackmd.io/D8KZubDcQEypx0r_izXflA) - 6/2 每日任務 Day40:[新增貼文留言功能](https://hackmd.io/jam5zo8pQYennLyiOSPh6g) - 6/3 每日任務 Day41:[取得所有貼文,加上 comment](https://hackmd.io/YVAJRCAdTS-l7uAtePjeOg) --- <!-- **第六週大綱** --> <!-- ^5/13(五)Day26^ - 使用 [bcryptjs](https://www.npmjs.com/package/bcryptjs) 套件將密碼加密,==題目==成功新增的資料密碼不能為明碼 ^5/16(一)Day27^ - [validator](https://www.npmjs.com/package/validator) 驗證使用者註冊資料(暱稱及密碼長度、email 格式)==題目==:新增 user 資料(POST `/sign_up`),、加入驗證 ^5/17(二)Day28^ - JWT 介紹,==題目==:使用 JWT 產生 token ^5/18(三)Day29^ - ==題目==:將 JWT 加入註冊功能(POST `/sign_up`)中 --> <!-- ^5/19(四)Day30^ - 使用 [bcryptjs](https://www.npmjs.com/package/bcryptjs) 套件將密碼解密比對是否符合(參考 [mongoose select()](https://mongoosejs.com/docs/api/query.html#:~:text=When%20using%20string%20syntax%2C%20prefixing%20a%20path%20with%20%2D%20will%20flag%20that%20path%20as%20excluded.%20When%20a%20path%20does%20not%20have%20the%20%2D%20prefix%2C%20it%20is%20included.%20Lastly%2C%20if%20a%20path%20is%20prefixed%20with%20%2B%2C%20it%20forces%20inclusion%20of%20the%20path%2C%20which%20is%20useful%20for%20paths%20excluded%20at%20the%20schema%20level.))、JWT 產生 token,==題目==:製作登入功能(POST `/sign_in`) ^5/20(五)Day31^ - 設計 isAuth 的 middleware 取得 request.header.authorization、驗證 token 是否正確([JWT 流程步驟 5](https://whimsical.com/jwt-UKUY1rj1vfoN6uyic7e4Sm)),==題目==:使用測試路由 GET `/test` 測試 isAuth middleware 是否有正確驗證 --> <!-- :::spoiler isAuth middleware ```javascript const isAuth = handleErrorAsync(async (req, res, next) => { // 確認 token 是否存在 let token; if ( req.headers.authorization && req.headers.authorization.startsWith('Bearer') ) { token = req.headers.authorization.split(' ')[1]; } if (!token) { return next(appError(401,'你尚未登入!',next)); } // 驗證 token 正確性 const decoded = await new Promise((resolve,reject)=>{ jwt.verify(token,process.env.JWT_SECRET,(err,payload)=>{ if(err){ reject(err) }else{ resolve(payload) } }) }) console.log(decoded); const currentUser = await User.findById(decoded.id); req.user = currentUser; next(); }); ``` ::: ^5/23(一)Day32^ - ==題目==:設計取得 user 資料路由 GET `/users/profile`,加入 isAuth middleware ^5/24(二)Day33^ - ==題目==:複習 [bcryptjs](https://www.npmjs.com/package/bcryptjs)、`generateSendJWT()`,設計重設密碼路由 PATCH **第七週大綱** - ==題目== multer 套件處理 request 傳過來的 `multipart/form-data` 資料,[multer(opts)](https://github.com/expressjs/multer#multeropts)、[fileFilter()](https://github.com/expressjs/multer#filefilter) 設定上傳圖檔驗證是否符合條件,完成上傳圖片 API - 註冊 Imgur 應用程式(參考[文件](https://apidocs.imgur.com/#intro) 中的 **Register an Application (IMPORTANT)** 介紹)申請 `Client ID` 及 `Client secret` - ==題目== [imgur 套件](https://www.npmjs.com/package/imgur/v/1.0.2)將圖片上傳至 imgur 空間 - [image-size 套件](https://github.com/image-size/image-size) 偵測圖片尺寸 --> **第八週大綱** - ==題目==:提供情境,回覆此情境的讀寫比例適合使用何種資料庫設計(embedded、一對一或一對多(關聯資料庫)) - ==題目==:提供情境,回覆此情境下,一個 document 是否會超過 16mb 的限制,依此判斷使用一對多 (1: few) 或一對多 (1: many) 的資料庫設計 <!-- - ==題目==:實作 POST DELETE 新增、取消一則貼文讚,posts Model 新增 likes 陣列 --> - ==題目== POST DELETE [追蹤與取消追蹤功能](https://github.com/hexschool/mongoose-post/blob/main/week8-mongooseAdvanced/routes/users.js#L79-L133) * [user model 增加欄位](https://github.com/hexschool/mongoose-post/blob/main/week8-mongooseAdvanced/models/users.js#L30-L47) - ==題目==: POST:[新增一則貼文的留言](https://github.com/hexschool/mongoose-post/blob/main/week8-mongooseAdvanced/routes/posts.js#L133-L144) * [增加 comment model](https://github.com/hexschool/mongoose-post/blob/main/week8-mongooseAdvanced/models/comment.js) * [post model 增加虛擬欄位 comments](https://github.com/hexschool/mongoose-post/blob/main/week8-mongooseAdvanced/models/posts.js#L37-L54) - ==題目== GET:[取得所有貼文,加上 comment](https://github.com/hexschool/mongoose-post/blob/main/week8-mongooseAdvanced/routes/posts.js#L22-L25)