node.js是什麼似乎已經不需要我多為贅述了,非阻塞的伺服器語言、JS書寫的背景代碼,無數的文章已經很好的展示了node的魅力與展望。關于node.js的安裝,大家不妨參考部落格園聶微東的http://www.cnblogs.com/Darren_code/archive/2011/10/31/nodejs.html (node.js初體驗),這篇文章很好的綜述了node.js的一個基礎(從安裝到體驗到子產品的一個入門,個人感覺是一篇很好的文章),相信通過東哥的這篇文章大家可以對node有一個初步的了解。
node是一門很有意思的架構,它能夠讓一個長期執迷于前端開發的攻城濕(忘記了還有一種語言叫後端語言。。。)能夠覺得很舒适(編碼習慣都一樣),但是也同樣會讓一個新手覺得無所适從(為什麼麼有從入門到精通哩?參考書在哪裡???)。這是一個前端高手為之一亮(也許隻亮了一眼o(╯□╰)o),新手眼前一暈(if you want to find more information,please read the source(╯□╰)o)的架構。為了讓和我一樣的新手能夠多多少少摸到一點門路,我以身試法,來為新手找一條路~
本文旨在新手入門,所學尚淺,代碼水準有限,這也僅僅隻是一個基本入門的筆記,高手可以笑一笑然後點關閉了。。。
首先我假設你已經安裝好了node(http://nodejs.org/#download,0.6.14已經很成熟了),那麼首先我們來進行一個入門的編碼分析。
在進行分析之前,我們先來想一下以前的伺服器端語言架構的工作原理。首先,使用者通過浏覽器來通路我們的應用。然後伺服器通過對端口的監聽,來接收網絡端的request請求,并進行相應的處理。最後再将處理的結果傳回用戶端。
好了,那麼我們可以開始了。首先是伺服器,要是沒有辦法啟動伺服器,那麼一切都是閑的。我們也許用過很多伺服器端的語言(PHP、JAVA、ASP等等),接收HTTP請求并提供Web頁面的過程似乎不用我們來做,apache和IIS似乎都會幫我們來完成。但是在node裡,這一步必須你自己做。我們來實作的不僅僅是一個應用,還需要實作HTTP處理的伺服器。
好像很複雜的樣子,但對于node這并不是什麼複雜的東西。我們即将進行一個HTTP伺服器的初步學習,但是在學習之前我們需要溫習(預習?)一下node的子產品機制。
node采取的是子產品機制(和JS差不多),通過對子產品的導入我們可以聲明變量并将導入的子產品的執行個體化對象賦給變量并加以使用。具體各個子產品的使用方法以及用途請參考API,這裡就不說了。。。
好了,我們回來看看HTTP伺服器的構成。首先,我們先對HTTP子產品進行一次請求:
var http = require("http");
在node中require方法用于對各個子產品的引入,在這裡我們需要對http子產品加以使用時就可以導入。導入後将之賦予http變量,然後對http變量進行操作。讓我們以hello world作為例子:
每每看到hello world時内心都會有一絲變态的快意。。。
讓我們來回憶一下剛才的問題:實作一個http的伺服器。其實這個很簡單,http子產品自帶的createServer方法就可以完成。該方法隻有一個參數,類型為函數,在接口文檔中的定義是“始終接收request事件”。而server.listen方法(server就是剛才通過createServer建立的server)的參數是(port, [hostname], [callback]),第一個是監聽的端口号,第二個和第三個是可選項,第二個是主機名稱,第三個回調函數。這個函數隻在綁定端口後進行調用。
接下來是回調函數,回調函數的參數有兩個,第一個是用戶端發送的request,第二個是伺服器端的response。這段代碼進行了一個簡單的響應操作。首先是書寫了一個響應頭,響應頭參數包括狀态碼、原因描述以及頭部内容。狀态碼即http狀态碼,例如200、404、500之類的。原因描述與頭部内容可選,具體的就參見網絡報頭的書寫了,這裡就不多說了(其實我也不會。。。)。writehead方法必須寫在end方法之前,這個是肯定的。。。
response的write方法就和JS的write所做的工作一樣,就是向頁面寫入資料,雖然原理不盡相同,但目前沒有準備去鑽研這部分源碼的我們可以忽略了。。。最後是end方法,它有兩個可選參數,分别是data與encoding。該方法用于所有的響應頭與響應正文輸出之後,進行響應的終結,并将管道流中的所有響應資料輸出。簡單地說就是在響應最後加上去的東西,它執行後會将響應執行。如果該方法帶有參數,那麼就相當于先調用了response.write(data, encoding)方法,之後再調用無參數的end方法。
好了,最簡單的一個http伺服器已經工作起來了。當使用者通路127.0.0.1的12345端口時伺服器會監聽到這一端口的request請求并書寫報頭與最簡單的helloworld于頁面上,使用者得到響應之後會在浏覽器中顯示響應的内容,也就是helloworld。這個最簡單的伺服器已經搭好了,但我們不能隻滿足于這一點。
在繼續下一步的學習之前,我想給所有沒有使用過JS或者不怎麼使用的同學大體的講述一下一個也許你們會略微奇怪的參數傳遞方法——函數傳遞。
在JS中,函數與數字、字元串等都是以var定義的,在參數傳遞的過程中所接受的參數也是var這種弱類型的。而function類型也是作為弱類型傳遞,當我們将一個函數進行傳遞時,所得到的不是該函數的傳回值,而是這個函數本身。也就是說,這個函數在運作時會變成傳遞到的函數的本地變量(自己都覺得好亂。。。)。
讓我們回憶一下剛才的例子,在creatServer方法中我們使用了一個匿名函數作為參數,現在我們把這個匿名函數提出來:


exports即module.exports對象,在node中可以作為全局變量的賦予。也就是說它一般用來定義全局變量的,多用于子產品間的變量傳遞。在此我需要簡單說一下JS的子產品機制,JS中的子產品多用閉包進行包裹(我也不知道這麼說對不對),而在閉包中定義的局部變量則無法在全局展開使用,也就是說别的地方調用這個子產品時不能将其中的局部變量單獨的進行使用。而exports則可以在載入子產品後将該函數載入全局變量的作用鍊中。
說到這大家也應該明白了,我們要進行一次子產品引用。将這段代碼存入serverRequest.js中,然後建立一個index.js檔案,然後引用serverRequest子產品:
這樣我們就進行了一個最基本的小子產品的搭建,也初步的了解了一下node的子產品體系。那麼下一步我們就要進行下連個個非常重要的子產品的學習,也就是url子產品與path子產品。
url子產品的作用是從請求中擷取請求的url并進行處理,它有着幾個常用的方法:
第一個方法的作用是擷取url請求部分的域名之後的路徑名稱,第二個方法擷取的則是通過get向伺服器傳遞的參數。
而path子產品的作用是解決檔案路徑問題,我們這次先學習三個方法:
第一個方法是擷取擴充名的方法,參數是url路徑。第二個方法是做路徑拼接使用,用來标準化最終路徑,參數是需要拼接的路徑。第三個方法是檢驗路徑存在與否,第一個參數是标準化的路徑,第二個是可選的回調函數,無論路徑存在與否都會被調用,函數有一個exist參數,标示路徑是否存在。
好了,現在我們就可以通過這兩個子產品進行一個簡單的路徑伺服器的搭建了。通過這個伺服器的搭建,我們可以對本地的靜态網站進行部署,對于頁面以及網頁所需要載入的各種資源進行尋址,最後對請求的資源進行回報。


這是當時對着一篇大牛的博文敲的例子,後來發現隻能載入單個網頁,而其他資源不能很好的載入,就進行了一次較大的改正,主要添加了對不同pathname的尋址以及載入。本例的css、js以及image檔案夾都與頁面所在的html檔案夾在同一目錄下。
相信通過這個例子大家已經能簡單的讓一個靜态網站在我們的伺服器上支援起來了。我們下一次将會簡單的部署一個檔案系統,希望大家能繼續關注。新手上道,文章代碼寫的都比較粗糙,希望大家指正。bye