摘要:然而,這一次,將有三個作為前三個命令行參數提供。編寫一個時間服務器服務器監聽一個端口,以獲取一些連接,這個端口會經由第一個命令行參數傳遞給程序。
learnyounode 13課總結(下)
前斷時間較為忙碌,所以learnyounode的下半部分總結一直拖到了現在,罪過罪過。那么今天我就將8-13課的內容整理出來,將后半部分的知識稍微梳理一下。
這里推薦一篇learnyounode的漢化版,它將learnyounode的界面翻譯并附出了答案,對于完成教程還是很有幫助的。(當然,不是抄。。。)
中文版地址:https://www.kancloud.cn/kancloud/learnyounode/47115
編寫一個程序,發起一個 HTTP GET 請求,請求的 URL 為所提供的命令行參數的第一個。收集所有服務器所返回的數據(不僅僅包括 “data” 事件)然后在終端(標準輸出 std out)用兩行打印出來。 所打印的內容,第一行應該是一個整數,用來表示收到的字符串內容長度,第二行則是服務器返回的完整的字符串結果。
首先需要確定的是,從6、7題我們知道了,在利用node發送請求的時候,數據是片段流的方式進行傳遞的,這就要求我們在收到請求之后,需要將完整的請求解析出來。
我們可以利用node的http模塊去請求一個接口,然后對接口返回對應的參數res進行事件處理。根據文檔可以知道res有error、data、end等事件,那這里我們只要對res做好事件處理就可以達到獲取所有請求信息的效果啦。下面是代碼~
const http = require("http"); http.get(process.argv[2],function(res){ let rawData = ""; res.on("data",function(data){ rawData += data; }) res.on("error",function(err){ console.log(err); }) res.on("end",function(data){ console.log(rawData.length); console.log(rawData); }) })lesson 9
這次的問題和之前的問題(HTTP 收集器)很像,也是需要使用到 http.get() 方法。然而,這一次,將有三個 URL 作為前三個命令行參數提供。 需要收集每一個 URL 所返回的完整內容,然后將它們在終端(標準輸出stdout)打印出來。這次不需要打印出這些內容的長度,僅僅是內容本身即可(字符串形式);每個 URL對應的內容為一行。重點是必須按照這些 URL 在參數列表中的順序將相應的內容排列打印出來才算完成。
本題與上題類似,獲取接口返回的完整信息應該相當容易了,難的是,如何將三個接口返回的信息順序打印出來。當然了,現在npm上的三方庫這么多,我們完全可以通過三方庫將接口請求事件順序排列,在完成一個接口之后輸出返回信息,然后再進行下一個請求。
不過我用的是以前在頁面中處理異步的笨方法。給每個接口事件對應一個狀態,請求接口成功并返回數據之后將對應狀態設為true,請求完成之后,所有接口狀態為true再順序輸出所有接口的返回信息。
http = require("http"); let isEnd1=false; let isEnd2=false; let isEnd3=false; let data1,data2,data3; http.get(process.argv[2],function(res){ let rawData = ""; res.on("data",function(data){ rawData += data; }) res.on("error",function(err){ console.log(err); }) res.on("end",function(data){ data1=rawData; isEnd1=true; if(isEnd1&&isEnd2&&isEnd3){ console.log(data1); console.log(data2); console.log(data3); } }) }) http.get(process.argv[3],function(res){ let rawData = ""; res.on("data",function(data){ rawData += data; }) res.on("error",function(err){ console.log(err); }) res.on("end",function(data){ data2=rawData; isEnd2=true; if(isEnd1&&isEnd2&&isEnd3){ console.log(data1); console.log(data2); console.log(data3); } }) }) http.get(process.argv[4],function(res){ let rawData = ""; res.on("data",function(data){ rawData += data; }) res.on("error",function(err){ console.log(err); }) res.on("end",function(data){ data3=rawData; isEnd3=true; if(isEnd1&&isEnd2&&isEnd3){ console.log(data1); console.log(data2); console.log(data3); } }) })lesson 10
編寫一個 TCP 時間服務器 服務器監聽一個端口,以獲取一些TCP連接,這個端口會經由第一個命令行參數傳遞給程序。針對每一個 TCP 連接,都必須寫入當前的日期和24小時制的時間,如下格式:"YYYY-MM-DD hh:mm" 然后緊接著是一個換行符。 月份、日、小時和分鐘必須用零填充成為固定的兩位數:"2013-07-06 17:42"
在提示中,本題是需要用net模塊去創建一個服務器,而不是用http模塊創建的。作為后端小白不懂tcp服務器和普通服務器的區別orz,希望了解的大神能提點一下。
在了解到用什么搭建服務器之后,后續的問題倒是不用擔心了,只需要記得把時間格式處理一下就行。下面是手動格式化時間的代碼,答案中好像有不用手動格式化的,找個時間研究一下它的寫法。
const net = require("net"); net.createServer(function(socket){ var date= new Date(); socket.end(formatDate(date)+" "); }).listen(process.argv[2]); function formatDate(datee){ var year = datee.getFullYear(); var month = datee.getMonth()+1; var date = datee.getDate(); var hour = datee.getHours(); var minute = datee.getMinutes(); var second = datee.getSeconds(); month = month < 10 ? "0"+month:month; date = date < 10 ? "0"+date:date; hour = hour < 10 ? "0"+hour:hour; minute = minute < 10 ? "0"+minute:minute; second = second < 10 ? "0"+second:second; return year+"-"+month+"-"+date+" "+hour+":"+minute; }lesson 11
編寫一個 HTTP 文件 服務器,它用于將每次所請求的文件返回給客戶端。 服務器需要監聽所提供的第一個命令行參數所制定的端口。 同時,第二個會提供給程序的參數則是所需要響應的文本文件的位置。在這一題中必須使用fs.createReadStream() 方法以 stream 的形式作出請求相應。
我們可以利用http和fs兩個模塊,在服務端發送請求的時候,去讀取文件的內容,并將它的內容作為流輸入到接口的返回中。只需要好好利用fs模塊的createStream方法即可完成任務。
在生成文件流之后,我們可以通過pipe方法將其輸入到接口的res里。pipe方法是獨屬于stream的一種方法,我們可以將其理解成流變量像通過管道一樣流向及輸出,是一種非常抽象的方法,使用的地方很多,我們可以多了解一下。
const http = require("http"); const fs = require("fs"); const server = http.createServer((req, res) => { const url = process.argv[3]; const fsdata = fs.createReadStream(url, { flags: "r", encoding: "utf-8", fd: null, mode: 0o666, autoClose: true }); fsdata.on("readable", () => { console.log("readable:", fsdata.read()); }).pipe(res); }); server.on("clientError", (err, socket) => { socket.end("HTTP/1.1 400 Bad Request "); }) server.on("error",(err) => { console.log(err); }) server.listen(Number(process.argv[2]), "127.0.0.1", () => { console.log("listen success"); });lesson 12
編寫一個 HTTP 服務器,它只接受 POST 形式的請求,并且將 POST 請求主體(body)所帶的字符轉換成大寫形式,然后返回給客戶端。 服務器需要監聽由第一個命令行參數所指定的端口。
在前端頁面中,最常見的有get和post兩種與接口進行交互的方式,而具體的方式則由接口來指定。這說明后端做接口的時候是可以對前端提交的所有信息進行篩選和判斷并加以利用的,這也是一般接口所做的事情。
提交給接口的所有信息都存在server的req參數里面,所以我們需要圍繞著這個參數做信息的判斷和提取,并將其返回。
const http = require("http"); http.createServer(function(req,res){ var postData = ""; req.addListener("data", function (postDataChunk) { if(req.method==="POST"){ postData += postDataChunk; } }); req.addListener("end", function(){ if(req.method==="POST"){ res.end(postData.toUpperCase(),"utf8"); } }); }).listen(process.argv[2]);lesson 13
編寫一個 HTTP 服務器,每當接收到一個路徑為 "/api/parsetime" 的 GET 請求的時候,響應一些 JSON 數據。我們期望請求會包含一個查詢參數(query string),key 是 “iso ,值是 ISO 格式的時間。 如: /api/parsetime?iso=2013-08-10T12:10:15.474Z 所響應的 JSON 應該只包含三個屬性:"hour","minute" 和 "second"。例如: { "hour": 14, "minute": 23, "second": 15 } 然后增再加一個接口,路徑為 "/api/unixtime",它可以接收相同的查詢參數(query strng),但是它的返回會包含一個屬性:"unixtime",相應值是一個 UNIX 時間戳。例如: { "unixtime": 1376136615474 } 服務器需要監聽第一個命令行參數所指定的端口。
最后一題的意思十分的簡單明了,利用前面所以題目學到的信息,正兒八經的寫一個給前端頁面用的接口。雖然接口功能十分簡單,可是涉及到了前端信息判斷、獲取、處理、返回等一連串系統的接口處理。
本題的難點在于,我們需要判斷信息提交的接口路徑來做出不同的處理,這種類似于路由的東西我們在前面的題目中都沒提到過。不過前文提到過了,server的req信息包含了所提交的所有信息,包括提交的接口路徑、提交方式、提交內容等等,所以我們按照提示中,利用url模塊將req中的url信息提取出來再做判斷即可達成目的。
( 題目中所提到的isotime比較難找,本文提供一個isotime以供測試:2016-01-18T23:41:00 )
const http = require("http"); const url = require("url"); const server = http.createServer((req, res) => { let urlObj = url.parse(req.url); let pathname = urlObj.pathname; if (pathname === "/api/parsetime") { let param = urlObj.query; if(param.indexOf("&") === -1){ let params = param.split("="); if(params[0] === "iso"){ let isotime = params[1]; let time = new Date(isotime); console.log(time); let resObj = { hour : time.getHours(), minute : time.getMinutes(), second : time.getSeconds() }; res.end(JSON.stringify(resObj)); } } }else if (pathname === "/api/unixtime") { let param = urlObj.query; if(param.indexOf("&") === -1){ let params = param.split("="); if(params[0] === "iso"){ let isotime = params[1]; let time = new Date(isotime); let timeTamp = time.getTime(); let resObj = { unixtime : timeTamp }; res.end(JSON.stringify(resObj)); } } } }) server.on("clientError", (err, socket) => { socket.end("HTTP/1.1 400 Bad Request "); }) server.on("error", (err) => { console.log(err); }) server.listen(Number(process.argv[2]), () => { console.log("listen success"); })
learnyounode的歸納總結到這里就結束了,感覺離node距離進了一步,不再是和以前一樣連node官方文檔都看不進去了。大致了解各個模塊的功能和調用方法,也終于將node和express算是區分開了一些哈哈哈。
我感覺learnyounode雖然沒有將node的方方面面包含進去,但是它確實適用于剛入門、對node一門霧水的人。它將node的重要模塊多帶帶或結合在一起,列出了它們的適用場景以及使用方法,題目難度適中,是需要看文檔去了解才能寫出來的。不過更大程度上我更喜歡它的提示,提示就是我們以后解決node問題的思路(提示幾乎是題題必看~還是太菜了~)。
在解題過程這段期間,也算是學到了不少東西,最起碼對后端平時所做的工作以及權限有了一定的了解,對node的各個模塊也有了一定的認識。這其中有不少知識只是自己的臆測,有失偏頗,只能等不斷深入慢慢修正觀念了。
在練習的過程中,感慨于fs以及http模塊的強大,大致了解到網頁爬蟲的工作原理,后面一段時間應該會寫一直爬蟲來鞏固深化這塊知識。在這立個flag,也算是為自己立個小目標吧~
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/89198.html
摘要:編寫一個簡單的程序,使其能接收一個或者多個命令行參數,并且在終端標準輸出中打印出這些參數的總和。處理所有可能發生的錯誤,并把它們傳遞給回調函數。編寫一個程序來發起一個請求,所請求的為命令行參數的第一個。 learnyounode 13課總結(上) 最近對nodejs比較感興趣,但是苦于無法下手,直接啃文檔又覺得十分生硬無趣。 幸好有熱心網友推薦了learnyounode這個好玩的入...
摘要:面對正在跑步進入大齡程序員隊列的我,對過去有一些思考總結,同時對未來也有一些想法?,F在想來大學時候最錯誤的決定就是學嵌入式,從后來找工作來看它的熱度根本不如應用軟件開發,并且物聯網也并沒有大熱,或許時代會真正迎來。15年畢業,算上實習經歷差不多有四年半的工作經驗。沒想到時間過得這么快,有時候還覺得跟剛畢業一樣。之前在創業公司呆過兩年半,目前在阿里做大數據/算法相關的工作。這四年來收獲過成功的...
摘要:編寫異步小爬蟲在通過的課程初步了解的各大模塊之后,不禁感慨于的強大,讓我們這些前端小白也可以進行進階的功能實現,同時發現自己也已經可以通過實現一些比較日常的小功能。 nodejs編寫異步小爬蟲 在通過learnyounode的課程初步了解nodejs的各大模塊之后,不禁感慨于nodejs的強大,讓我們這些前端小白也可以進行進階的功能實現,同時發現自己也已經可以通過nodejs實現一些...
安裝搭建項目的開發環境 視頻地址:https://www.cctalk.com/v/15114357764004 showImg(https://segmentfault.com/img/remote/1460000012470016?w=1214&h=718); 文章 Koa 起手 - 環境準備 由于 koa2 已經開始使用 async/await 等新語法,所以請保證 node 環境在 7.6...
閱讀 2581·2021-11-22 12:01
閱讀 1105·2021-11-15 11:37
閱讀 3685·2021-09-22 14:59
閱讀 1746·2021-09-04 16:45
閱讀 1382·2021-09-03 10:30
閱讀 1013·2021-08-11 11:18
閱讀 2459·2019-08-30 10:53
閱讀 2013·2019-08-29 15:13