一、 安裝
首先,去http://nodejs.org 下載安裝。我下的版本是0.8.14。安裝很簡單,下一步下一步就哦了。然後在path中配置一下安裝目錄即可,msi會把npm(Node Package Manager)一併裝上。
我的安裝目錄是C:/Program Files (x86)/nodejs。這時使用cmd命令窗口node -v , npm -v命令查看下安裝的版本
1.1、helloworld
在Node.js工程目錄中新建一個文件hello.js,裡面敲一行代碼
console.log('hello, nodejs.') ;進入命令行控制台,進入到Node.js工程目錄敲node hello.js
控制台輸出了“hello, nodejs.”
1.2、web版的helloworld
在Node.js工程目錄中新建一個http.js,代碼如下
var http = require("http");http.createServer(function(request, response) { response.writeHead(200, {"Content-Type": "text/html"}); response.write("Hello World!"); response.end();}).listen(8000);在命令行中啟動服務,敲node http.js
然後打開瀏覽器地址欄輸入http://localhost:8000/,看見頁面上輸出Hello World! 就成功了。
node.js的版本一定和API同步
node.js的版本號有規律,偶數版本為穩定版本,奇數版本非穩定版本
2 HelloWorld代碼分析
好啦,從現在開始逐行分析我們的HelloWorld。
引入模塊
var http = require("http");require方法用來引入一個模塊,參數是模塊的名字。比如File System模塊,可以這麼引入:
var fs = require("fs");我們可以把require()方法當做全局方法使用,但實際上它更像屬於某個模塊的本地方法,它的文檔參考這裡:https://nodejs.org/api/globals.html。
require方法返回某個模塊的實例,比如require(“http”)就返回一個HTTP實例。 HTTP實例的參考文檔在這裡:https://nodejs.org/api/http.html。
我們看到,HTTP模塊有一個方法createServer(),就牽涉到我們的第二行代碼了。
創建服務器
HTTP模塊的createServer()方法,接受一個方法作為參數,原型為:
http.createServer([requestListener])
requestListener是一個方法,會與http.Server類的request事件關聯起來。這樣當客戶端請求到達時,requestListener就會被調用。
requestListener有兩個參數,函數原型如下:
function (request, response) { }第一個參數request的類型是http.IncomingMessage ,實現了Readable Stream接口。
第二個參數的類型是http.ServerResponse ,實現了Writeable Stream接口。
Stream的API在這裡:https://nodejs.org/api/stream.html。同時,request和response還是EventEmitter,可以發射特定的事件。
EventEmitter的API在這裡:https://nodejs.org/api/events.html#events_class_events_eventemitter,後面我們會講如何使用EventEmitter來發射事件、處理事件。
再回顧一下我們創建server的代碼:
http.createServer( function(request, response) { response.writeHead(200, {"Content-Type": "text/plain"}); response.write("Hello World!"); response.end(); }).listen(8000);http.createServer返回一個http.Server實例,http.Server的listen方法可以讓服務器監聽在某個端口上,示例中是8000。
如你所見,我們提供了一個匿名函數給createServer方法。在這個方法中,我們通過response參數向客戶端回寫了“Hello World!”消息。
分析客戶端請求
前面我們分析了http.createServer方法,它的參數是一個帶兩個參數的方法,一個代表了客戶端發過來的請求,一個代表了要回寫給客戶端的響應。我們來看看request參數。
request是http.IncomingMessage的實例,通過這個實例,我們可以拿到請求參數,比如HTTP方法、HTTP版本、url、頭部等,具體的API在這裡:https://nodejs.org/api/http.html#http_http_incomingmessage。
我們通過修改HelloWorld.js來看看(另存為HelloWorld2.js)。代碼如下:
// 引入http模塊var http = require("http"); // 創建server,指定處理客戶端請求的函數http.createServer( function(request, response) { console.log("method - " + request.method); console.log("version - " + request.httpVersion); console.log("url - " + request.url); response.writeHead(200, {"Content-Type": "text/plain"}); response.write("Hello World!"); response.end(); }).listen(8000); console.log("Hello World start listen on port 8000");如你所見,我使用console這個對象來輸出了一些調試信息,打印了HTTP方法、版本、url等信息。可以執行node HelloWorld2.js,瀏覽器訪問http://localhost:8000,然後跑到命令行看看輸出了什麼信息,我這裡是這樣的:
我們簡簡單單的HelloWorld已經可以發送一些響應數據給客戶端,你在瀏覽器裡能看到“Hello World!”字樣。這個響應是通過http.ServerResponse的實例response發送給客戶端的。
http.ServerResponse也是一個Stream ,還是一個EventEmitter。我們通過它給客戶度返回HTTP狀態碼、數據、HTTP頭部等信息。
HTTP模塊
在Node.js的HTTP模塊,狀態行就是通過http.ServerResponse的writeHead方法寫給客戶端的。 writeHead方法原型如下:
response.writeHead(statusCode[, statusMessage][, headers])
這個方法的第一個參數,就是statusCode,也就是200、403之類的數字,剩下的參數是可選的。最後一個參數是headers,你可以在這裡使用JSON對象表示法來寫一些HTTP頭部,比如: {“Content-Type”:”text/plain”,”Content-Length”:11} 。第一個可選參數statusMessage用來指定一個狀態描述消息,可以不填寫。
HTTP頭部
頭部就是一些key-value對,比如我們在HelloWorld裡看到的”Content-Type”,就是用來說明數據類型的頭部標籤,對應的可能是文本文件、圖片、視頻、二進制等。類似的還有”Content-Length”,用來指定數據長度。還有很多很多,比如”Date”、”Connection”等。具體還是參考前面的鏈接吧。
頭部還可以使用http.ServerResponse的response.setHeader(name, value)方法來單獨設置,一次可以設置一個HTTP頭部。
數據
頭部之後就是數據了,有些狀態碼,比如200,後續都會有一些數據。而有些,比如301、404、403、500之類的,多數沒有數據。
數據通過http.ServerResponse的write方法來寫回給客戶端,比如這樣:
response.setHeader("Content-Type", "text/html");這裡要提一點,HTTP常見的數據傳輸編碼方式有兩種:
設置Content-Length,傳輸固定長度的數據設置Transfer-Encoding頭部為chunked,分塊傳輸數據
像我們現在的HelloWorld示例,沒有設置Content-Length頭部,Node.js的HTTP模塊就默認為chunked編碼。
我們使用Chrome瀏覽器的開發者工具來查看網絡數據,可以很明確的看到。如下圖所示:
HTTP響應
我標註出來的三處,都是HelloWorld示例傳遞給瀏覽器的HTTP頭部信息。
我們通過http.ServerResponse的write方法向客戶端寫數據。你可以一次寫入所有數據,也可以把數據分開來多次寫入。當要傳輸的數據量較大時,分多次寫入就是比較合理的做法,比如你向客戶端發送大文件,就比較適合分多次寫入,也可以利用Node.js的異步特性,獲得不錯的性能。