摘要:然而,這一次,將有三個(gè)作為前三個(gè)命令行參數(shù)提供。編寫(xiě)一個(gè)時(shí)間服務(wù)器服務(wù)器監(jiān)聽(tīng)一個(gè)端口,以獲取一些連接,這個(gè)端口會(huì)經(jīng)由第一個(gè)命令行參數(shù)傳遞給程序。
learnyounode 13課總結(jié)(下)
前斷時(shí)間較為忙碌,所以learnyounode的下半部分總結(jié)一直拖到了現(xiàn)在,罪過(guò)罪過(guò)。那么今天我就將8-13課的內(nèi)容整理出來(lái),將后半部分的知識(shí)稍微梳理一下。
這里推薦一篇learnyounode的漢化版,它將learnyounode的界面翻譯并附出了答案,對(duì)于完成教程還是很有幫助的。(當(dāng)然,不是抄。。。)
中文版地址:https://www.kancloud.cn/kancloud/learnyounode/47115
編寫(xiě)一個(gè)程序,發(fā)起一個(gè) HTTP GET 請(qǐng)求,請(qǐng)求的 URL 為所提供的命令行參數(shù)的第一個(gè)。收集所有服務(wù)器所返回的數(shù)據(jù)(不僅僅包括 “data” 事件)然后在終端(標(biāo)準(zhǔn)輸出 std out)用兩行打印出來(lái)。 所打印的內(nèi)容,第一行應(yīng)該是一個(gè)整數(shù),用來(lái)表示收到的字符串內(nèi)容長(zhǎng)度,第二行則是服務(wù)器返回的完整的字符串結(jié)果。
首先需要確定的是,從6、7題我們知道了,在利用node發(fā)送請(qǐng)求的時(shí)候,數(shù)據(jù)是片段流的方式進(jìn)行傳遞的,這就要求我們?cè)谑盏秸?qǐng)求之后,需要將完整的請(qǐng)求解析出來(lái)。
我們可以利用node的http模塊去請(qǐng)求一個(gè)接口,然后對(duì)接口返回對(duì)應(yīng)的參數(shù)res進(jìn)行事件處理。根據(jù)文檔可以知道res有error、data、end等事件,那這里我們只要對(duì)res做好事件處理就可以達(dá)到獲取所有請(qǐng)求信息的效果啦。下面是代碼~
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
這次的問(wèn)題和之前的問(wèn)題(HTTP 收集器)很像,也是需要使用到 http.get() 方法。然而,這一次,將有三個(gè) URL 作為前三個(gè)命令行參數(shù)提供。 需要收集每一個(gè) URL 所返回的完整內(nèi)容,然后將它們?cè)诮K端(標(biāo)準(zhǔn)輸出stdout)打印出來(lái)。這次不需要打印出這些內(nèi)容的長(zhǎng)度,僅僅是內(nèi)容本身即可(字符串形式);每個(gè) URL對(duì)應(yīng)的內(nèi)容為一行。重點(diǎn)是必須按照這些 URL 在參數(shù)列表中的順序?qū)⑾鄳?yīng)的內(nèi)容排列打印出來(lái)才算完成。
本題與上題類似,獲取接口返回的完整信息應(yīng)該相當(dāng)容易了,難的是,如何將三個(gè)接口返回的信息順序打印出來(lái)。當(dāng)然了,現(xiàn)在npm上的三方庫(kù)這么多,我們完全可以通過(guò)三方庫(kù)將接口請(qǐng)求事件順序排列,在完成一個(gè)接口之后輸出返回信息,然后再進(jìn)行下一個(gè)請(qǐng)求。
不過(guò)我用的是以前在頁(yè)面中處理異步的笨方法。給每個(gè)接口事件對(duì)應(yīng)一個(gè)狀態(tài),請(qǐng)求接口成功并返回?cái)?shù)據(jù)之后將對(duì)應(yīng)狀態(tài)設(shè)為true,請(qǐng)求完成之后,所有接口狀態(tài)為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
編寫(xiě)一個(gè) TCP 時(shí)間服務(wù)器 服務(wù)器監(jiān)聽(tīng)一個(gè)端口,以獲取一些TCP連接,這個(gè)端口會(huì)經(jīng)由第一個(gè)命令行參數(shù)傳遞給程序。針對(duì)每一個(gè) TCP 連接,都必須寫(xiě)入當(dāng)前的日期和24小時(shí)制的時(shí)間,如下格式:"YYYY-MM-DD hh:mm" 然后緊接著是一個(gè)換行符。 月份、日、小時(shí)和分鐘必須用零填充成為固定的兩位數(shù):"2013-07-06 17:42"
在提示中,本題是需要用net模塊去創(chuàng)建一個(gè)服務(wù)器,而不是用http模塊創(chuàng)建的。作為后端小白不懂tcp服務(wù)器和普通服務(wù)器的區(qū)別orz,希望了解的大神能提點(diǎn)一下。
在了解到用什么搭建服務(wù)器之后,后續(xù)的問(wèn)題倒是不用擔(dān)心了,只需要記得把時(shí)間格式處理一下就行。下面是手動(dòng)格式化時(shí)間的代碼,答案中好像有不用手動(dòng)格式化的,找個(gè)時(shí)間研究一下它的寫(xiě)法。
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
編寫(xiě)一個(gè) HTTP 文件 服務(wù)器,它用于將每次所請(qǐng)求的文件返回給客戶端。 服務(wù)器需要監(jiān)聽(tīng)所提供的第一個(gè)命令行參數(shù)所制定的端口。 同時(shí),第二個(gè)會(huì)提供給程序的參數(shù)則是所需要響應(yīng)的文本文件的位置。在這一題中必須使用fs.createReadStream() 方法以 stream 的形式作出請(qǐng)求相應(yīng)。
我們可以利用http和fs兩個(gè)模塊,在服務(wù)端發(fā)送請(qǐng)求的時(shí)候,去讀取文件的內(nèi)容,并將它的內(nèi)容作為流輸入到接口的返回中。只需要好好利用fs模塊的createStream方法即可完成任務(wù)。
在生成文件流之后,我們可以通過(guò)pipe方法將其輸入到接口的res里。pipe方法是獨(dú)屬于stream的一種方法,我們可以將其理解成流變量像通過(guò)管道一樣流向及輸出,是一種非常抽象的方法,使用的地方很多,我們可以多了解一下。
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
編寫(xiě)一個(gè) HTTP 服務(wù)器,它只接受 POST 形式的請(qǐng)求,并且將 POST 請(qǐng)求主體(body)所帶的字符轉(zhuǎn)換成大寫(xiě)形式,然后返回給客戶端。 服務(wù)器需要監(jiān)聽(tīng)由第一個(gè)命令行參數(shù)所指定的端口。
在前端頁(yè)面中,最常見(jiàn)的有g(shù)et和post兩種與接口進(jìn)行交互的方式,而具體的方式則由接口來(lái)指定。這說(shuō)明后端做接口的時(shí)候是可以對(duì)前端提交的所有信息進(jìn)行篩選和判斷并加以利用的,這也是一般接口所做的事情。
提交給接口的所有信息都存在server的req參數(shù)里面,所以我們需要圍繞著這個(gè)參數(shù)做信息的判斷和提取,并將其返回。
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
編寫(xiě)一個(gè) HTTP 服務(wù)器,每當(dāng)接收到一個(gè)路徑為 "/api/parsetime" 的 GET 請(qǐng)求的時(shí)候,響應(yīng)一些 JSON 數(shù)據(jù)。我們期望請(qǐng)求會(huì)包含一個(gè)查詢參數(shù)(query string),key 是 “iso ,值是 ISO 格式的時(shí)間。 如: /api/parsetime?iso=2013-08-10T12:10:15.474Z 所響應(yīng)的 JSON 應(yīng)該只包含三個(gè)屬性:"hour","minute" 和 "second"。例如: { "hour": 14, "minute": 23, "second": 15 } 然后增再加一個(gè)接口,路徑為 "/api/unixtime",它可以接收相同的查詢參數(shù)(query strng),但是它的返回會(huì)包含一個(gè)屬性:"unixtime",相應(yīng)值是一個(gè) UNIX 時(shí)間戳。例如: { "unixtime": 1376136615474 } 服務(wù)器需要監(jiān)聽(tīng)第一個(gè)命令行參數(shù)所指定的端口。
最后一題的意思十分的簡(jiǎn)單明了,利用前面所以題目學(xué)到的信息,正兒八經(jīng)的寫(xiě)一個(gè)給前端頁(yè)面用的接口。雖然接口功能十分簡(jiǎn)單,可是涉及到了前端信息判斷、獲取、處理、返回等一連串系統(tǒng)的接口處理。
本題的難點(diǎn)在于,我們需要判斷信息提交的接口路徑來(lái)做出不同的處理,這種類似于路由的東西我們?cè)谇懊娴念}目中都沒(méi)提到過(guò)。不過(guò)前文提到過(guò)了,server的req信息包含了所提交的所有信息,包括提交的接口路徑、提交方式、提交內(nèi)容等等,所以我們按照提示中,利用url模塊將req中的url信息提取出來(lái)再做判斷即可達(dá)成目的。
( 題目中所提到的isotime比較難找,本文提供一個(gè)isotime以供測(cè)試: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的歸納總結(jié)到這里就結(jié)束了,感覺(jué)離node距離進(jìn)了一步,不再是和以前一樣連node官方文檔都看不進(jìn)去了。大致了解各個(gè)模塊的功能和調(diào)用方法,也終于將node和express算是區(qū)分開(kāi)了一些哈哈哈。
我感覺(jué)learnyounode雖然沒(méi)有將node的方方面面包含進(jìn)去,但是它確實(shí)適用于剛?cè)腴T(mén)、對(duì)node一門(mén)霧水的人。它將node的重要模塊多帶帶或結(jié)合在一起,列出了它們的適用場(chǎng)景以及使用方法,題目難度適中,是需要看文檔去了解才能寫(xiě)出來(lái)的。不過(guò)更大程度上我更喜歡它的提示,提示就是我們以后解決node問(wèn)題的思路(提示幾乎是題題必看~還是太菜了~)。
在解題過(guò)程這段期間,也算是學(xué)到了不少東西,最起碼對(duì)后端平時(shí)所做的工作以及權(quán)限有了一定的了解,對(duì)node的各個(gè)模塊也有了一定的認(rèn)識(shí)。這其中有不少知識(shí)只是自己的臆測(cè),有失偏頗,只能等不斷深入慢慢修正觀念了。
在練習(xí)的過(guò)程中,感慨于fs以及http模塊的強(qiáng)大,大致了解到網(wǎng)頁(yè)爬蟲(chóng)的工作原理,后面一段時(shí)間應(yīng)該會(huì)寫(xiě)一直爬蟲(chóng)來(lái)鞏固深化這塊知識(shí)。在這立個(gè)flag,也算是為自己立個(gè)小目標(biāo)吧~
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/89198.html
摘要:編寫(xiě)一個(gè)簡(jiǎn)單的程序,使其能接收一個(gè)或者多個(gè)命令行參數(shù),并且在終端標(biāo)準(zhǔn)輸出中打印出這些參數(shù)的總和。處理所有可能發(fā)生的錯(cuò)誤,并把它們傳遞給回調(diào)函數(shù)。編寫(xiě)一個(gè)程序來(lái)發(fā)起一個(gè)請(qǐng)求,所請(qǐng)求的為命令行參數(shù)的第一個(gè)。 learnyounode 13課總結(jié)(上) 最近對(duì)nodejs比較感興趣,但是苦于無(wú)法下手,直接啃文檔又覺(jué)得十分生硬無(wú)趣。 幸好有熱心網(wǎng)友推薦了learnyounode這個(gè)好玩的入...
摘要:面對(duì)正在跑步進(jìn)入大齡程序員隊(duì)列的我,對(duì)過(guò)去有一些思考總結(jié),同時(shí)對(duì)未來(lái)也有一些想法?,F(xiàn)在想來(lái)大學(xué)時(shí)候最錯(cuò)誤的決定就是學(xué)嵌入式,從后來(lái)找工作來(lái)看它的熱度根本不如應(yīng)用軟件開(kāi)發(fā),并且物聯(lián)網(wǎng)也并沒(méi)有大熱,或許時(shí)代會(huì)真正迎來(lái)。15年畢業(yè),算上實(shí)習(xí)經(jīng)歷差不多有四年半的工作經(jīng)驗(yàn)。沒(méi)想到時(shí)間過(guò)得這么快,有時(shí)候還覺(jué)得跟剛畢業(yè)一樣。之前在創(chuàng)業(yè)公司呆過(guò)兩年半,目前在阿里做大數(shù)據(jù)/算法相關(guān)的工作。這四年來(lái)收獲過(guò)成功的...
摘要:編寫(xiě)異步小爬蟲(chóng)在通過(guò)的課程初步了解的各大模塊之后,不禁感慨于的強(qiáng)大,讓我們這些前端小白也可以進(jìn)行進(jìn)階的功能實(shí)現(xiàn),同時(shí)發(fā)現(xiàn)自己也已經(jīng)可以通過(guò)實(shí)現(xiàn)一些比較日常的小功能。 nodejs編寫(xiě)異步小爬蟲(chóng) 在通過(guò)learnyounode的課程初步了解nodejs的各大模塊之后,不禁感慨于nodejs的強(qiáng)大,讓我們這些前端小白也可以進(jìn)行進(jìn)階的功能實(shí)現(xiàn),同時(shí)發(fā)現(xiàn)自己也已經(jīng)可以通過(guò)nodejs實(shí)現(xiàn)一些...
安裝搭建項(xiàng)目的開(kāi)發(fā)環(huán)境 視頻地址:https://www.cctalk.com/v/15114357764004 showImg(https://segmentfault.com/img/remote/1460000012470016?w=1214&h=718); 文章 Koa 起手 - 環(huán)境準(zhǔn)備 由于 koa2 已經(jīng)開(kāi)始使用 async/await 等新語(yǔ)法,所以請(qǐng)保證 node 環(huán)境在 7.6...
閱讀 2596·2021-11-22 12:01
閱讀 1121·2021-11-15 11:37
閱讀 3707·2021-09-22 14:59
閱讀 1768·2021-09-04 16:45
閱讀 1400·2021-09-03 10:30
閱讀 1035·2021-08-11 11:18
閱讀 2473·2019-08-30 10:53
閱讀 2026·2019-08-29 15:13