NodeJS系(xi)列~第一個小例子(zi),實(shi)現了(le)request.querystring功能
百度百科上:
Node.js是(shi)一(yi)套(tao)用來(lai)編寫高性能網絡服(fu)務器的(de)JavaScript工(gong)具(ju)包,一(yi)系列(lie)的(de)變化由此開始,在(zai)Node中(zhong),Http是(shi)首要的(de)。Node為(wei)創建http服(fu)務器作了優化,所以在(zai)網上看到的(de)大(da)部分示例和庫都(dou)是(shi)集中(zhong)在(zai)web上(http框架、模板(ban)庫等)。
Node.js的優點
下面我愉前(qian)人(ren)寫的一個(ge)資料(liao),讓(rang)大(da)家更清(qing)楚的了解NodeJS,
Node 旨在解決什么問題?
Node 公開宣稱的(de)(de)(de)目(mu)標(biao)是 “旨在(zai)(zai)提供一種簡單(dan)的(de)(de)(de)構建可伸(shen)縮網絡程序的(de)(de)(de)方(fang)法”。當(dang)前的(de)(de)(de)服(fu)務器(qi)程序有什(shen)么問(wen)題(ti)(ti)?我們來(lai)做個(ge)(ge)數學題(ti)(ti)。在(zai)(zai) Java? 和 PHP 這(zhe)(zhe)類語(yu)言中,每個(ge)(ge)連接(jie)都會(hui)生成一個(ge)(ge)新線程,每個(ge)(ge)新線程可能需(xu)要 2 MB 的(de)(de)(de)配套內存。在(zai)(zai)一個(ge)(ge)擁有 8 GB RAM 的(de)(de)(de)系統上(shang),理論上(shang)最大的(de)(de)(de)并發(fa)連接(jie)數量是 4,000 個(ge)(ge)用(yong)戶(hu)。隨著您(nin)的(de)(de)(de)客戶(hu)群(qun)的(de)(de)(de)增(zeng)長,如果希望您(nin)的(de)(de)(de) Web 應(ying)用(yong)程序支持更多用(yong)戶(hu),那么,您(nin)必(bi)須添加(jia)(jia)更多服(fu)務器(qi)。當(dang)然,這(zhe)(zhe)會(hui)增(zeng)加(jia)(jia)服(fu)務器(qi)成本(ben)(ben)、流量成本(ben)(ben)和人工成本(ben)(ben)等成本(ben)(ben)。除(chu)這(zhe)(zhe)些成本(ben)(ben)上(shang)升外,還(huan)有一個(ge)(ge)潛在(zai)(zai)技術問(wen)題(ti)(ti),即 用(yong)戶(hu)可能針對(dui)每個(ge)(ge)請(qing)求使用(yong)不(bu)同(tong)的(de)(de)(de)服(fu)務器(qi),因此,任(ren)何共享(xiang)(xiang)資源都必(bi)須在(zai)(zai)所(suo)有服(fu)務器(qi)之間(jian)共享(xiang)(xiang)。鑒于上(shang)述所(suo)有原因,整個(ge)(ge) Web 應(ying)用(yong)程序架構(包括流量、處(chu)理器(qi)速度(du)和內存速度(du))中的(de)(de)(de)瓶頸是:服(fu)務器(qi)能夠處(chu)理的(de)(de)(de)并發(fa)連接(jie)的(de)(de)(de)最大數量。
Node 解決這個問題的(de)方法是:更改連接到服務器(qi)的(de)方式。每(mei)個連接發射一個在 Node 引擎的(de)進程(cheng)中運(yun)行的(de)事件,而不(bu)是為每(mei)個連接生成一個新的(de) OS 線程(cheng)(并為其分(fen)配(pei)(pei)一些配(pei)(pei)套內存)。Node 聲稱(cheng)它絕(jue)不(bu)會死鎖(suo),因為它根本不(bu)允許使用鎖(suo),它不(bu)會直(zhi)接阻塞 I/O 調用。Node 還(huan)宣稱(cheng),運(yun)行它的(de)服務器(qi)能支持數萬個并發連接。
現在(zai)您有了一個(ge)能處理(li)(li)數萬個(ge)并發(fa)連(lian)接(jie)的(de)(de)程序,那(nei)么您能通過 Node 實際構建什么呢?如(ru)果您有一個(ge) Web 應(ying)用程序需要處理(li)(li)這么多連(lian)接(jie),那(nei)將是(shi)一件很 “恐怖” 的(de)(de)事!那(nei)是(shi)一種 “如(ru)果您有這個(ge)問題(ti),那(nei)么它根本(ben)不是(shi)問題(ti)” 的(de)(de)問題(ti)。在(zai)回答上面的(de)(de)問題(ti)之前,我們先看(kan)看(kan) Node 的(de)(de)工作原理(li)(li)以及它的(de)(de)設計運(yun)行方式(shi)。
Node 肯定不是什么?
沒錯,Node 是一個服務器程序。但是,基礎 Node 產品肯定不 像 Apache 或 Tomcat。本質上,那些(xie)服(fu)務(wu)器(qi) “安裝就緒(xu)型” 服(fu) 務(wu)器(qi)產(chan)品,支持立即部署應用(yong)程序。通過這(zhe)些(xie)產(chan)品,您(nin)可以(yi)在(zai)一(yi)分(fen)鐘(zhong)內啟動(dong)并運行一(yi)個(ge)(ge)(ge)服(fu)務(wu)器(qi)。Node 肯定不是(shi)這(zhe)種產(chan)品。Apache 能通過添(tian)加(jia)一(yi)個(ge)(ge)(ge) PHP 模(mo)塊(kuai)(kuai)(kuai)(kuai)來允(yun)(yun)許(xu)開發人員創建動(dong)態 Web 頁,添(tian)加(jia)一(yi)個(ge)(ge)(ge) SSL 模(mo)塊(kuai)(kuai)(kuai)(kuai)來實(shi)現安全(quan)連(lian)接,與此類似,Node 也有(you)模(mo)塊(kuai)(kuai)(kuai)(kuai)概念,允(yun)(yun)許(xu)向(xiang) Node 內核添(tian)加(jia)模(mo)塊(kuai)(kuai)(kuai)(kuai)。實(shi)際(ji)上,可供選(xuan)擇(ze)的(de)(de)用(yong)于 Node 的(de)(de)模(mo)塊(kuai)(kuai)(kuai)(kuai)有(you)數(shu)百(bai)個(ge)(ge)(ge)之多,社(she)區在(zai)創建、發布和更新模(mo)塊(kuai)(kuai)(kuai)(kuai)方面非常活躍,一(yi)天甚至可以(yi)處(chu)理數(shu)十(shi)個(ge)(ge)(ge)模(mo)塊(kuai)(kuai)(kuai)(kuai)。本文(wen)后面將討(tao)論 Node 的(de)(de)整個(ge)(ge)(ge)模(mo)塊(kuai)(kuai)(kuai)(kuai)部分(fen)。
Node 如何工作?
Node 本(ben)身(shen)運行 V8 JavaScript。等(deng)(deng)等(deng)(deng),服務(wu)器上的(de) JavaScript?沒(mei)錯(cuo),您沒(mei)有看錯(cuo)。對于只(zhi)在(zai)客戶(hu)機上使用(yong) JavaScript 的(de)程序員而言,服務(wu)器端 JavaScript 可能(neng)是一(yi)個(ge)新概念,但這個(ge)概念本(ben)身(shen)并非(fei)遙不可及,因此為(wei)何(he)不能(neng)在(zai)服務(wu)器上使用(yong)客戶(hu)機上使用(yong)的(de)編程語言?
什么是 V8?V8 JavaScript 引擎是 Google 用于其 Chrome 瀏覽器的底層 JavaScript 引擎。很少有人考慮 JavaScript 在客戶機上實際做了些什么?實際上,JavaScript 引擎負責解釋并執行代碼。Google 使用 V8 創建了一個用 C++ 編寫的超快解釋器,該解釋器擁有另一個獨特特征;您可以下載該引擎并將其嵌入任何 應用程(cheng)序。V8 JavaScript 引(yin)擎并不僅限于(yu)在一個(ge)(ge)瀏(liu)覽器中(zhong)運行。因(yin)此,Node 實際上會使(shi)用 Google 編寫的(de) V8 JavaScript 引(yin)擎,并將(jiang)其重建為(wei)可在服務器上使(shi)用。太完美(mei)了!既然已(yi)經(jing)有一個(ge)(ge)不錯的(de)解決(jue)方案(an)可用,為(wei)何還要創(chuang)建一種新語言呢?
事件驅動編程
許多程(cheng)序員接受的(de)(de)教育使他(ta)們認為,面(mian)向對象編(bian)程(cheng)是完美的(de)(de)編(bian)程(cheng)設計(ji),這使得他(ta)們對其(qi)他(ta)編(bian)程(cheng)方法不屑一(yi)顧。Node 使用(yong)了一(yi)個所謂的(de)(de)事件驅動編(bian)程(cheng)模型。
清單 1. 客戶端上使用 jQuery 的事件驅動編程
// jQuery code on the client-side showing how Event-Driven programming works // When a button is pressed, an Event occurs - deal with it // directly right here in an anonymous function, where all the // necessary variables are present and can be referenced directly $("#myButton").click(function(){ if ($("#myTextField").val() != $(this).val()) alert("Field must match button text"); });
實際上,服務器端和客戶端沒有任何區別。沒錯,這沒有按鈕點擊操作,也沒有向文本字段鍵入的操作,但在一個更高的層面上,事件正在 發生。一(yi)個(ge)連(lian)接(jie)被建立(li),這(zhe)是(shi)(shi)一(yi)個(ge)事件(jian)(jian)!數據通(tong)過(guo)(guo)連(lian)接(jie)進行接(jie)收,這(zhe)也是(shi)(shi)一(yi)個(ge)事件(jian)(jian)!數據通(tong)過(guo)(guo)連(lian)接(jie)停止,這(zhe)還(huan)是(shi)(shi)一(yi)個(ge)事件(jian)(jian)!
為 什么這種設(she)置類(lei)型對(dui) Node 很理想?JavaScript 是一種很棒(bang)的(de)(de)事(shi)件驅動編程語(yu)言(yan),因為它允許使用匿名函(han)數(shu)和閉包(bao),更重要的(de)(de)是,任何寫過(guo)代碼的(de)(de)人都熟悉它的(de)(de)語(yu)法。事(shi)件發生時調(diao)用的(de)(de)回(hui)調(diao)函(han)數(shu)可以在捕獲事(shi)件處 進行編寫。這樣可以使代碼容易編寫和維護,沒有復(fu)雜的(de)(de)面向對(dui)象框架(jia),沒有接口,沒有過(guo)度(du)設(she)計的(de)(de)可能性。只需監(jian)聽事(shi)件,編寫一個回(hui)調(diao)函(han)數(shu),其他事(shi)情都可以交 給系統處理!
擴展的模塊
模(mo)塊(kuai)(kuai)中包含了很多功能代碼片(pian)斷,在模(mo)塊(kuai)(kuai)中的代碼大部分都是(shi)私有的,意思是(shi)在模(mo)塊(kuai)(kuai)中定義的函數方法和變(bian)量(liang),都只能在同一個模(mo)塊(kuai)(kuai)中被調(diao)用(yong)。當然,可以將某(mou)些方法和變(bian)量(liang)暴(bao)露到(dao)模(mo)塊(kuai)(kuai)外,這個時候可以使(shi)用(yong)export對象去實現
首先需要安裝nodejs環境,相關文件下載
下載之后,安裝之后,在C盤(pan)就會出現nodejs的相關目錄(lu)
OK,我們來看(kan)一下如何實現request.querystring功能(neng)的,即get請求的功能(neng),相關代碼如下:
var qs = require('querystring'); var http = require('http'); var formidable = require('formidable'); var exec = require('child_process').exec; var fs = require('fs'); var filename = ''; var url = require("url"); function start(response, request) { var getQuery = url.parse(request.url).query; var getData = qs.parse(getQuery); //getData數據(ju) console.log(getData["zzl"]); }
別外一種比(bi)較標準的寫(xie)法(fa)重到querystring字符串,寫(xie)法(fa)如下:
var http = require("http"); var url = require("url"); var params = url.parse(request.url, true).query; console.log(params.zzl);
感覺第(di)二(er)種寫法更清晰
測試:
//127.0.0.1:8888?zzl=1234
對(dui)于nodejs的(de)console控(kong)制(zhi)臺的(de)結果就(jiu)為: