Node.js基礎
一、Node.js介紹
Node.js是一個javascript運行環境。它讓javascript可以開發后端程序,實現幾乎其他后端語言實現的所有功能,可以與PHP、Java、Python、.NET、Ruby等后端語言平起平坐。
Nodejs是基於V8引擎,V8是Google發布的開源JavaScript引擎,本身就是用於Chrome瀏覽器的js解釋部分,但是Ryan Dahl 這哥們,鬼才般的,把這個V8搬到了服務器上,用於做服務器的軟件。
二、node.js的優勢
1、Nodejs語法完全是js語法,只要你懂js基礎就可以學會Nodejs后端開發
Node打破了過去JavaScript只能在瀏覽器中運行的局面。前后端編程環境統一,可以大大降低開發成本。
2、NodeJs超強的高並發能力
NodeJs的首要目標是提供一種簡單的、用於創建高性能服務器及可在該服務器中運行的各種應用程序的開發工具。
首先讓我們來看一下現在的服務器端語言中存在着什么問題。在Java、PHP或者.NET等服務器語言中,會為每一個客戶端連接創建一個新的線程。而每個線程需要耗費大約2MB內存。也就是說,理論上,一個8GB內存的服務器可以同時連接的最大用戶數為4000個左右。要讓web應用程序支持更多的用戶,就需要增加服務器的數量,而web應用程序的硬件成本當然就上升了。
NodeJs不為每個客戶連接創建一個新的線程,而僅僅使用一個線程。當有用戶連接了,就觸發一個內部事件,通過非阻塞I/O、事件驅動機制,讓Node.js程序宏觀上也是並行的。使用Node.js,一個8GB內存的服務器,可以同時處理超過4萬用戶的連接。
3、實現高性能服務器
嚴格地說,Node.js是一個用於開發各種web服務器的開發工具。在Node.js服務器中,運行的是高性能V8 JavaScript腳本語言,該語言是一種可以運行在服務器端的腳本語言。
那么,什么是V8 JavaScript腳本語言呢?該語言是一種被V8 JavaScript引擎所解析並執行的腳本語言。V8 JavaScript引擎是由Google公司使用C++語言開發的一種高性能JavaScript引擎,該引擎並不局限於在瀏覽器中運行。Node.js將其轉用在了服務器中,並且為其提供了許多附加的具有各種不同用途的API。例如,在一個服務器中,經常需要處理各種二進制數據。在JavaScript腳本語言中,只具有非常有限的對二進制數據的處理能力,而Node.js所提供的Buffer類則提供了豐富的對二進制數據的處理能力。
另外,在V8 JavaScript引擎內部使用一種全新的編譯技術。這意味着開發者編寫的高端的 JavaScript 腳本代碼與開發者編寫的低端的C語言具有非常相近的執行效率,這也是Node.js服務器可以提供的一個重要特性。
4、開發周期短、開發成本低、學習成本低
Node.js自身哲學,是話最小的硬件成本,追求更高的並發,更高的處理性能。
三、NodeJS的特點
我們先來看看NodeJS官網上的介紹:
Node.js is a platform built on Chrome’s JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.
其特點為:
- 它是一個Javascript運行環境
- 依賴於Chrome V8引擎進行代碼解釋
- 異步事件驅動
- 非阻塞I/O
- 輕量、可伸縮,適於實時數據交互應用
- 單進程,單線程(這里指主線程)
- 性能出眾
接下來就對以上幾點進行簡單的闡述:
一、V8虛擬機
根據百度百科解釋,Node.js是一套用來編寫高性能網絡服務器的JavaScript工具包。Node.js是一個可以快速構建網絡服務及應用的平台,該平台的構建是基於Chrome's JavaScript runtime,也就是說,實際上它是對GoogleV8引擎(應用於Google Chrome瀏覽器)進行了封裝。V8引 擎執行Javascript的速度非常快,性能非常好。
NodeJS並不是提供簡單的封裝,然后提供API調用,如果是這樣的話那么它就不會有現在這么火了。Node對一些特殊用例進行了優化,提供了替代的API,使得V8在非瀏覽器環境下運行得更好。例如,在服務器環境中,處理二進制數據通常是必不可少的,但Javascript對此支持不足,因此,V8.Node增加了Buffer類,方便並且高效地 處理二進制數據。因此,Node不僅僅簡單的使用了V8,還對其進行了優化,使其在各環境下更加給力。
二、事件驅動
首先,解釋下“事件驅動”這個概念。所謂事件驅動,是指在持續事務管理過程中,進行決策的一種策略,即跟隨當前時間點上出現的事件,調動可用資源,執行相關任務,使不斷出現的問題得以解決,防止事務堆積。
Nodejs設計思想中以事件驅動為核心,事件驅動在於異步回調,他提供的大多數api都是基於事件的、異步的風格。而事件驅動的優勢在於充分利用系統資源,執行代碼無須阻塞等待某種操作完成,有限的資源用於其他任務。事件驅動機制是通過內部單線程高效率地維護事件循環隊列來實現的,沒有多線程的資源占用和上下文的切換。
Node.js 使用事件驅動模型,當web server接收到請求,就把它關閉然后進行處理,然后去服務下一個web請求。
當這個請求完成,它被放回處理隊列,當到達隊列開頭,這個結果被返回給用戶。
這個模型非常高效可擴展性非常強,因為webserver一直接受請求而不等待任何讀寫操作。(這也被稱之為非阻塞式IO或者事件驅動IO)
在事件驅動模型中,會生成一個主循環來監聽事件,當檢測到事件時觸發回調函數。
三、異步、非堵塞I/O
Nodejs提供的很多模塊中都是異步執行的。比如,文件操作的函數。
一個異步I/O的大致流程:
- 發起I/O調用
①用戶通過js代碼調用nodejs的核心模塊,將回調函數和參數傳入核心模塊
②將回調函數和參數封裝成
- 執行回調
①操作完成將結果儲存到請求對象的result屬性上,並發出完成通知。
②循環事件,如果有未完成的,就在進入對象請求I/O觀察者隊列,之后當做事件處理;
非阻塞 I/O,也叫異步 I/O,顯然對應的就是阻塞式 I/O。
傳統的服務器語言大多是多線程、阻塞式 I/O。這也是 Node 與眾不同的地方,對於傳統的服務器語言,在與用戶建立連接時,每一個連接都是一個線程。 當有十萬個用戶連接時,服務器上就會有十萬個線程。而阻塞式 I/O 是指,當一個線程在執行 I/O 操作時,這個線程會阻塞,等待 I/O 操作完成后繼續執行。
舉個例子可以更好理解,比如我們到一個餐館吃飯,這個餐館比較高級,服務員是一對一服務(每個用戶都是一個線程),從我們坐下開始,服務員就把菜單給你,然后在旁邊等你點菜(等待 I/O 操作),當你看完菜單,把要點的菜告訴服務員( I/O 操作結束后線程繼續執行)。在你看菜單的過程中,服務員其實是被閑置的,如果你一直看,他就會一直等,直到你點完( I/O 操作結束)。這就是阻塞式 I/O。
阻塞式 I/O 必須要多線程,就這個例子來看,如果只有一個服務員(單線程),那當店里同時有十個顧客時,他需要一個一個等待顧客看菜單然后點菜,那后面的顧客要等待的時間就會很長,顯然這個餐館的服務就會很差(服務器性能差)。
所以傳統的服務器都是多線程、阻塞式 I/O,也就是相當於有多個服務員(線程),每個進來的顧客都分配到一個服務員(線程),然后你看菜單時在旁邊等候(阻塞式 I/O )。很明顯這樣的服務是讓顧客最舒服的,但是對於餐館老板來說很難受,因為要雇佣大量的服務員。因此傳統的方式成本是比較大的。要有性能足夠好的服務器才能支撐大量的線程。但他的優點也很明顯,比如某一桌客人與服務員發生爭吵(線程崩了!),不會影響到其他顧客,因為每一桌都有專門的服務員負責,因此只會對當前用戶產生影響。
上面的例子應該可以很好地理解多線程、阻塞式 I/O 。而 node 的特性是單線程、非阻塞時 I/O 。node 最大的優勢就是性能強,同樣的服務器性能使用 node 可以比傳統的服務器語言多容納一百倍的用戶(對於不同的任務有不同的差別, I/O 操作越多,node優勢越明顯,如果都是 CPU 計算任務,那他倆幾乎沒有區別(上面的例子中,忽略顧客的看菜單時間)。
還是用上面的例子再比喻一下單線程、非阻塞式 I/O 。這應該是個規模比較小的餐館,或者說老板比較窮,雇不起大量的服務員,因此只能雇佣一個服務員。當有顧客來時,服務員把菜單送過去,顧客開始看菜單( I/O 操作),這個時候,服務員是被釋放了的,他不用等待顧客看菜單,服務員說:“您先看着菜單,點好了叫我”(回調函數)。這個時候這個服務員就可以抽身去服務其他的顧客。用這種模式的話,一個服務員就可以服務多位顧客,而且不需要等待 I/O ,只需要隨時監聽就行了,顧客點完后會主動叫服務員(執行回調函數)。
單線程、非阻塞式 I/O 的優勢就是性能強,一個人服務員就可以解決大量顧客。但是他的缺點也很明顯,比如有一桌顧客和服務員又吵架了(線程崩了!),那這些顧客就都完了,因為所有人都在等這一個服務員。也就是說,如果線程崩掉了,那與這個服務器連接的所有用戶都會崩潰。
四、單線程
Nodejs跟Nginx一樣都是單線程為基礎的,這里的單線程指主線程為單線程,所有的阻塞的全部放入一個線程池中,然后主線程通過隊列的方式跟線程池來協作。我們寫js部分不需要關心線程的問題,簡單了解就可以了,主要由一堆callback回調構成的,然后主線程在循環過在適當場合調用。
Nodejs與操作系統交互,我們在 Javascript中調用的方法,最終都會通過 process.binding 傳遞到 C/C++ 層面,最終由他們來執行真正的操作。Node.js 即這樣與操作系統進行互動。
nodejs所謂的單線程,只是主線程是單線程,所有的網絡請求或者異步任務都交給了內部的線程池去實現,本身只負責不斷的往返調度,由事件循環不斷驅動事件執行。
Nodejs之所以單線程可以處理高並發的原因,得益於libuv層的事件循環機制,和底層線程池實現。
Event loop就是主線程從主線程的事件隊列里面不停循環的讀取事件,驅動了所有的異步回調函數的執行,Event loop總共7個階段,每個階段都有一個任務隊列,當所有階段被順序執行一次后,event loop 完成了一個 tick。
五、性能出眾
底層選擇用c++和v8來實現的,上面第一點講到過,nodejs的事件驅動機制,這意味着面對大規模的http請求,nodejs是憑借事件驅動來完成的,性能部分是不用擔心的,並且很出色。
四、NodeJS帶來的對系統瓶頸的解決方案
它的出現確實能為我們解決現實當中系統瓶頸提供了新的思路和方案,下面我們看看它能解決什么問題
1. 並發連接
舉個例子,想象一個場景,我們在銀行排隊辦理業務,我們看看下面兩個模型
(1)系統線程模型:
這種模型的問題顯而易見,服務端只有一個線程,並發請求(用戶)到達只能處理一個,其余的要先等待,這就是阻塞,正在享受服務的請求阻塞后面的請求了
(2)多線程、線程池模型:
這個模型已經比上一個有所進步,它調節服務端線程的數量來提高對並發請求的接收和響應,但並發量高的時候,請求仍然需要等待,它有個更嚴重的問題:
回到代碼層面上來講,我們看看客戶端請求與服務端通訊的過程:
服務端與客戶端每建立一個連接,都要為這個連接分配一套配套的資源,主要體現為系統內存資源,以PHP為例,維護一個連接可能需要20M的內存
這就是為什么一般並發量一大,就需要多開服務器
那么NodeJS是怎么解決這個問題的呢?
我們來看另外一個模型,想象一下我們在快餐店點餐吃飯的場景
(3)異步、事件驅動模型
我們同樣是要發起請求,等待服務器端響應;但是與銀行例子不同的是,這次我們點完餐后拿到了一個號碼,
拿到號碼,我們往往會在位置上等待,而在我們后面的請求會繼續得到處理,同樣是拿了一個號碼然后到一旁等待,接待員能一直進行處理。
等到飯菜做號了,會喊號碼,我們拿到了自己的飯菜,進行后續的處理(吃飯)
這個喊號碼的動作在NodeJS中叫做回調(Callback),能在事件(燒菜,I/O)處理完成后繼續執行后面的邏輯(吃飯),
這體現了NodeJS的顯著特點,異步機制、事件驅動
整個過程沒有阻塞新用戶的連接(點餐),也不需要維護已經點餐的用戶與廚師的連接
基於這樣的機制,理論上陸續有用戶請求連接,NodeJS都可以進行響應,因此NodeJS能支持比Java、PHP程序更高的並發量
雖然維護事件隊列也需要成本,再由於NodeJS是單線程,事件隊列越長,得到響應的時間就越長,並發量上去還是會力不從心
總結一下NodeJS是怎么解決並發連接這個問題的:
更改連接到服務器的方式,每個連接發射(emit)一個在NodeJS引擎進程中運行的事件(Event),放進事件隊列當中,
而不是為每個連接生成一個新的OS線程(並為其分配一些配套內存)
2. I/O阻塞
NodeJS解決的另外一個問題是I/O阻塞,看看這樣的業務場景:需要從多個數據源拉取數據,然后進行處理
(1)串行獲取數據,這是我們一般的解決方案,以PHP為例
假如獲取profile和timeline操作各需要1S,那么串行獲取就需要2S
(2)NodeJS非阻塞I/O,發射/監聽事件來控制執行過程
NodeJS遇到I/O事件會創建一個線程去執行,然后主線程會繼續往下執行的,
因此,拿profile的動作觸發一個I/O事件,馬上就會執行拿timeline的動作,
兩個動作並行執行,假如各需要1S,那么總的時間也就是1S
它們的I/O操作執行完成后,發射一個事件,profile和timeline,
事件代理接收后繼續往下執行后面的邏輯,這就是NodeJS非阻塞I/O的特點
總結一下:
Java、PHP也有辦法實現並行請求(子線程),但NodeJS通過回調函數(Callback)和異步機制會做得很自然
五、NodeJS的優缺點
優點:
1. 高並發(最重要的優點)
2. 適合I/O密集型應用
缺點:
1. 不適合CPU密集型應用;CPU密集型應用給Node帶來的挑戰主要是:由於JavaScript單線程的原因,如果有長時間運行的計算(比如大循環),將會導致CPU時間片不能釋放,使得后續I/O無法發起;
解決方案:分解大型運算任務為多個小任務,使得運算能夠適時釋放,不阻塞I/O調用的發起;
2. 只支持單核CPU,不能充分利用CPU
3. 可靠性低,一旦代碼某個環節崩潰,整個系統都崩潰
原因:單進程,單線程
解決方案:(1)Nnigx反向代理,負載均衡,開多個進程,綁定多個端口;
(2)開多個進程監聽同一個端口,使用cluster模塊;
4. 開源組件庫質量參差不齊,更新快,向下不兼容
5. Debug不方便,錯誤沒有stack trace
六、適合NodeJS的場景
- RESTful API
這是NodeJS最理想的應用場景,可以處理數萬條連接,本身沒有太多的邏輯,只需要請求API,組織數據進行返回即可。它本質上只是從某個數據庫中查找一些值並將它們組成一個響應。由於響應是少量文本,入站請求也是少量的文本,因此流量不高,一台機器甚至也可以處理最繁忙的公司的API需求。
- 統一Web應用的UI層
目前MVC的架構,在某種意義上來說,Web開發有兩個UI層,一個是在瀏覽器里面我們最終看到的,另一個在server端,負責生成和拼接頁面。
不討論這種架構是好是壞,但是有另外一種實踐,面向服務的架構,更好的做前后端的依賴分離。如果所有的關鍵業務邏輯都封裝成REST調用,就意味着在上層只需要考慮如何用這些REST接口構建具體的應用。那些后端程序員們根本不操心具體數據是如何從一個頁面傳遞到另一個頁面的,他們也不用管用戶數據更新是通過Ajax異步獲取的還是通過刷新頁面。
- 大量Ajax請求的應用
例如個性化應用,每個用戶看到的頁面都不一樣,緩存失效,需要在頁面加載的時候發起Ajax請求,NodeJS能響應大量的並發請求。 總而言之,NodeJS適合運用在高並發、I/O密集、少量業務邏輯的場景。
-
適合I/O密集型的應用
如在線多人聊天,多人在線小游戲,實時新聞,博客,微博之類的。
不適合的場景有:cpu密集型的應用
如計算圓周率,視頻解碼等業務場景較多的。
那么什么是I/O密集型,CPU密集型呢?下面詳細介紹下:
CPU密集型(CPU-bound)
CPU密集型也叫計算密集型,指的是系統的硬盤、內存性能相對CPU要好很多,此時,系統運作大部分的狀況是CPU Loading 100%,CPU要讀/寫I/O(硬盤/內存),I/O在很短的時間就可以完成,而CPU還有許多運算要處理,CPU Loading很高。
在多重程序系統中,大部份時間用來做計算、邏輯判斷等CPU動作的程序稱之CPU bound。例如一個計算圓周率至小數點一千位以下的程序,在執行的過程當中絕大部份時間用在三角函數和開根號的計算,便是屬於CPU bound的程序。
CPU bound的程序一般而言CPU占用率相當高。這可能是因為任務本身不太需要訪問I/O設備,也可能是因為程序是多線程實現因此屏蔽掉了等待I/O的時間。
IO密集型(I/O bound)
IO密集型指的是系統的CPU性能相對硬盤、內存要好很多,此時,系統運作,大部分的狀況是CPU在等I/O (硬盤/內存) 的讀/寫操作,此時CPU Loading並不高。
I/O bound的程序一般在達到性能極限時,CPU占用率仍然較低。這可能是因為任務本身需要大量I/O操作,而pipeline做得不是很好,沒有充分利用處理器能力。
CPU密集型 vs IO密集型
我們可以把任務分為計算密集型和IO密集型。
計算密集型任務的特點是要進行大量的計算,消耗CPU資源,比如計算圓周率、對視頻進行高清解碼等等,全靠CPU的運算能力。這種計算密集型任務雖然也可以用多任務完成,但是任務越多,花在任務切換的時間就越多,CPU執行任務的效率就越低,所以,要最高效地利用CPU,計算密集型任務同時進行的數量應當等於CPU的核心數。
計算密集型任務由於主要消耗CPU資源,因此,代碼運行效率至關重要。Python這樣的腳本語言運行效率很低,完全不適合計算密集型任務。對於計算密集型任務,最好用C語言編寫。
第二種任務的類型是IO密集型,涉及到網絡、磁盤IO的任務都是IO密集型任務,這類任務的特點是CPU消耗很少,任務的大部分時間都在等待IO操作完成(因為IO的速度遠遠低於CPU和內存的速度)。對於IO密集型任務,任務越多,CPU效率越高,但也有一個限度。常見的大部分任務都是IO密集型任務,比如Web應用。
IO密集型任務執行期間,99%的時間都花在IO上,花在CPU上的時間很少,因此,用運行速度極快的C語言替換用Python這樣運行速度極低的腳本語言,完全無法提升運行效率。對於IO密集型任務,最合適的語言就是開發效率最高(代碼量最少)的語言,腳本語言是首選,C語言最差。
總之,計算密集型程序適合C語言多線程,I/O密集型適合腳本語言開發的多線程。
結尾
其實NodeJS能實現幾乎一切的應用,我們考慮的點只是適不適合用它來做。
Node.js的安裝及基本使用
Node.js 安裝配置
Node.js支持在 Windows 、Linux以及在Mac 上安裝使用
安裝非常簡單,無復雜操作;就不多做贅述,掛個連接參考:https://www.runoob.com/nodejs/nodejs-install-setup.html
安裝完成,我們可以使用以下命令來查看當前的 Node 版本:
$ node -v
v4.4.3
注意:不同版本間可能是有差異的。
nvm介紹及使用(推薦使用node版本管理工具)
#一、介紹
nvm全名node.js version management,顧名思義是一個nodejs的版本管理工具。通過它可以安裝和切換不同版本的nodejs
為了解決node各種版本存在不兼容現象
nvm是讓你在同一台機器上安裝和切換不同版本的node的工具
我們可能同時在進行2個項目,而2個不同的項目所使用的node版本又是不一樣的,或者是要用更新的node版本進行試驗和學習。這種情況下,對於維護多個版本的node將會是一件非常麻煩的事情,而nvm就是為解決這個問題而產生的,他可以方便的在同一台設備上進行多個node版本之間切換,而這個正是nvm的價值所在,詳情可以查看官網NVM官網。
官網地址:https://github.com/nvm-sh/nvm
#二、安裝
兩種方式
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.0/install.sh | bash
wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.33.0/install.sh | bash
此時nvm就被安裝在了/.nvm下啦
驗證是否安裝成功
打開命令行,執行nvm -v命令后,出現提示說明安裝成功。
#三、基本使用安裝/管理nodejs
##1、查看本地安裝的所有版本;有可選參數available,顯示所有可下載的版本。
nvm list [available]
nvm ls
##2、安裝,命令中的版本號可自定義,具體參考命令1查詢出來的列表
nvm install 11.13.0
##3、使用特定版本,切換node的版本,這個是全局的
nvm use 11.13.0
##4、卸載
nvm uninstall 11.13.0
##列出所有可以安裝的node版本號
nvm ls-remote
##當前node版本
nvm current
#四、命令提示
nvm arch :顯示node是運行在32位還是64位。
nvm install <version> [arch] :安裝node, version是特定版本也可以是最新穩定版本latest。可選參數arch指定安裝32位還是64位版本,默認是系統位數。可以添加--insecure繞過遠程服務器的SSL。
nvm list [available] :顯示已安裝的列表。可選參數available,顯示可安裝的所有版本。list可簡化為ls。
nvm on :開啟node.js版本管理。
nvm off :關閉node.js版本管理。
nvm proxy [url] :設置下載代理。不加可選參數url,顯示當前代理。將url設置為none則移除代理。
nvm node_mirror [url] :設置node鏡像。默認是https://nodejs.org/dist/。如果不寫url,則使用默認url。設置后可至安裝目錄settings.txt文件查看,也可直接在該文件操作。
nvm npm_mirror [url] :設置npm鏡像。https://github.com/npm/cli/archive/。如果不寫url,則使用默認url。設置后可至安裝目錄settings.txt文件查看,也可直接在該文件操作。
nvm uninstall <version> :卸載指定版本node。
nvm use [version] [arch] :使用制定版本node。可指定32/64位。
nvm root [path] :設置存儲不同版本node的目錄。如果未設置,默認使用當前目錄。
nvm version :顯示nvm版本。version可簡化為v。
第一個Node.js程序:Hello World!
腳本模式
以下是我們的第一個Node.js程序:
實例
console.log("Hello World");
保存該文件,文件名為 helloworld.js, 並通過 node命令來執行:
node helloworld.js
程序執行后,正常的話,就會在終端輸出 Hello World。
交互模式
打開終端,鍵入node進入命令交互模式,可以輸入一條代碼語句后立即執行並顯示結果,例如:
$ node
> console.log('Hello World!');
Hello World!
Node.js 創建第一個應用
如果我們使用 PHP 來編寫后端的代碼時,需要 Apache 或者 Nginx 的 HTTP 服務器,並配上 mod_php5 模塊和 php-cgi。
從這個角度看,整個"接收 HTTP 請求並提供 Web 頁面"的需求就不需要 PHP 來處理。
不過對 Node.js 來說,概念完全不一樣了。使用 Node.js 時,我們不僅僅 在實現一個應用,同時還實現了整個 HTTP 服務器。事實上,我們的 Web 應用以及對應的 Web 服務器基本上是一樣的。
在我們創建 Node.js 第一個 "Hello, World!" 應用前,讓我們先了解下 Node.js 應用是由哪幾部分組成的:
- 引入 required 模塊:我們可以使用 require 指令來載入 Node.js 模塊。
- 創建服務器:服務器可以監聽客戶端的請求,類似於 Apache 、Nginx 等 HTTP 服務器。
- 接收請求與響應請求 服務器很容易創建,客戶端可以使用瀏覽器或終端發送 HTTP 請求,服務器接收請求后返回響應數據。
創建 Node.js 應用
步驟一、引入 required 模塊
我們使用 require 指令來載入 http 模塊,並將實例化的 HTTP 賦值給變量 http,實例如下:
var http = require("http");
步驟二、創建服務器
接下來我們使用 http.createServer() 方法創建服務器,並使用 listen 方法綁定 8888 端口。 函數通過 request, response 參數來接收和響應數據。
實例如下,在你項目的根目錄下創建一個叫 server.js 的文件,並寫入以下代碼:
var http = require('http');
http.createServer(function (request, response) {
// 發送 HTTP 頭部
// HTTP 狀態值: 200 : OK
// 內容類型: text/plain
response.writeHead(200, {'Content-Type': 'text/plain'});
// 發送響應數據 "Hello World"
response.end('Hello World\n');
}).listen(8888);
// 終端打印如下信息
console.log('Server running at http://127.0.0.1:8888/');
以上代碼我們完成了一個可以工作的 HTTP 服務器。
使用 node 命令執行以上的代碼:
node server.js
Server running at http://127.0.0.1:8888/
接下來,打開瀏覽器訪問 http://127.0.0.1:8888/,你會看到一個寫着 "Hello World"的網頁。
分析Node.js 的 HTTP 服務器:
- 第一行請求(require)Node.js 自帶的 http 模塊,並且把它賦值給 http 變量。
- 接下來我們調用 http 模塊提供的函數: createServer 。這個函數會返回 一個對象,這個對象有一個叫做 listen 的方法,這個方法有一個數值參數, 指定這個 HTTP 服務器監聽的端口號。