淺談Node.js開發Web伺服器
本文介紹下node.js是如何開發後端伺服器的,如有錯誤還望指出。
一、伺服器基礎知識
1.1 網站的組成
-
網站應用程式主要分為兩大部分:客戶端和伺服器端。
-
客戶端:在瀏覽器中執行的部分,就是使用者看到並與之互動的介面程式。使用HTML、CSS、JavaScript構建。
-
伺服器端:在伺服器中執行的部分,負責儲存資料和處理應用邏輯。
1.2 Node網站伺服器
能夠提供網站訪問服務的機器就是網站伺服器,它能夠接收客戶端的請求(request),能夠對請求做出響應(response)。
1.3 IP地址
網際網路中裝置的唯一標識。IP是lnternet Protocol Address的簡寫,代表網際網路協議地址。
1.4 域名
由於IP地址難於記憶,所以產生了域名的概念,所謂域名就是平時上網所使用的網址。
https://www.baidu.com/ => http://202.108.22.5/
雖然在位址列中輸入的是網址但是最終還是會將域名轉換為ip才能訪問到指定的網站伺服器
1.5 埠
埠是計算機與外界通訊交流的出口,用來區分伺服器電腦中提供的不同的服務。
舉個例子,埠可以用實際生活中的食堂來形容,不同的打菜視窗有不同的菜式,提供不同的服務。同樣,伺服器的埠也是如此,80埠對應的是HTTP(訪問web伺服器)開放的,25埠對應的是SMTP(簡單郵件傳輸協議),主要用於傳送郵件等等。
1.6 URL
統一資源定位符
URL的組成
傳輸協議://伺服器IP或域名:埠/資源所在位置標識
http://www.cnblogs.com/pick/
①http:超文字傳輸協議,提供了一種釋出和接收HTML頁面的方法。(後面詳細介紹)
②pick:資源所在位置標識
問:統一資源定位符是指定伺服器中資原始檔夾嗎?
答:不對,因為在伺服器中是可以拿到客戶端的請求地址,然後對應返回的結果是伺服器端說了算,如,訪問的是a.html,伺服器就給你訪問b.html,這是完全可以的。
1.7 開發過程中客戶端和伺服器端說明
在開發階段,客戶端(瀏覽器)和伺服器端(Node)使用同一臺電腦,即開發人員電腦。
-
本機域名:localhost
-
本地IP :127.0.0.1
1.8 HTTP協議
1.8.1 HTTP協議的概念
超文字傳輸協議(英文: HyperText Transfer Protocol,縮寫:HTTP)規定了如何從網站伺服器傳輸超文字到本地瀏覽器,它基於客戶端伺服器架構工作,是客戶端(使用者)和伺服器端(網站)請求和應答的標準。
超文字:包含圖片、視訊、音訊等等,實際上指的是html文字。
1.8.2 報文
在HTTP請求和響應的過程中傳遞的資料塊就叫報文,包括要傳送的資料和一些附加資訊,並且要遵守規定好的格式。通俗的講就是冒號開頭的鍵值對。
開啟Chrome的網路除錯可以看到如下內容
1.8.3請求報文
1.請求方式(Request Method)
-
GET 請求資料:獲取請求
-
POST 傳送資料:新增資料、登陸、POST相當於GET安全。
2.請求地址(Request URL)
3.獲取請求方法(Request Method)
1.8.4響應報文
1.HTTP狀態碼
-
200 請求成功
-
404 請求的資源沒有被找到
-
500 伺服器端錯誤
-
400 客戶端請求有語法錯誤
2.內容型別
-
text/html
-
text/css
-
application/javascript
-
image/jpeg
-
application/json
二、node基礎知識
什麼是Node?
Node是一個基於Chrome V8引擎的JavaScript程式碼執行環境,能夠使得javascript脫離瀏覽器執行。適合開發聊天室,部落格系統,考試系統等網站。
舉個例子:
比如,想泡壺茶喝。當時的情況是:開水沒有;水壺要洗,茶壺茶杯要洗;火生了,茶葉也有了。怎麼辦?
第一種:洗好水壺,灌上涼水,放在火上;在等待水開的時間裡,洗茶壺、洗茶杯、拿茶葉;等水開了,泡茶喝。
第二種:先做好一些準備工作,洗水壺,洗茶壺茶杯,拿茶葉;一切就緒,灌水燒水;坐待水開了泡茶喝。
第三種:洗淨水壺,灌上涼水,放在火上,坐待水開;水開了之後,急急忙忙找茶葉,洗茶壺茶杯,泡茶喝。
哪一種辦法省時間?我們能一眼看出第一種辦法好,後兩種辦法都窩了工。
顯然,Node.js是第一種方法,有著非阻塞和事件驅動的特性。
執行環境
-
瀏覽器(軟體)能夠執行JavaScript程式碼,瀏覽器就是JavaScript程式碼的執行環境
-
Node(軟體)能夠執行JavaScript程式碼,Node就是JavaScript程式碼的執行環境
為什麼選擇Node使用?
-
JavaScript語法開發後端應用
-
一些公司要求前端工程師掌握Node開發
-
生態系統活躍,有大量開源庫可以使用
-
前端開發工具大多基於Node開發
Node.js的組成
-
JavaScript 由三部分組成,ECMAScript,DOM,BOM。
-
Node.js是由ECMAScript及Node 環境提供的一些附加API組成的,包括檔案、網路、路徑等等一些更加強大的 API。
JavaScript:
-
ECMAScript:JavaScript語言的核心,規定了語言的語法部分DOM
-
BOM:瀏覽器為了讓他們控制,為這門語言提供的API
Node.js:
-
ECMAScript:Node.js語言的核心,規定了語言的語法部分
-
node環境提供api
Node.js 特點
- 事件驅動:在 Node.js 中,客戶端請求建立連線,提交資料等行為,會觸發相應的事件。Node.js 在一個時刻,只能執行一個事件回撥函式,但是在執行一個事件回撥函式的中途,可以轉而處理其他事件,然後返回繼續執行原事件的回撥函式。
- 非阻塞 I/O:Node.js 中採用了非阻塞型 I/O 機制,在執行了訪問資料庫的程式碼之後,將立即轉而執行其後面的程式碼,把資料庫返回結果的處理程式碼放在回撥函式中,從而提高了程式的執行效率。
- 輕量可伸縮,適用於實時資料互動應用。
- 單執行緒:好處是減少記憶體開銷,不用像多執行緒程式設計那樣處處在意狀態同步的問題。缺點是錯誤會引起整個應用的退出。
Node.js基礎語法
所有ECMASCript語法在Node環境中都可以使用。
在Node環境下執行程式碼,使用Node命令執行字尾為js的檔案即可
Node.js全域性物件global
在瀏覽器中全域性物件是window,在Node中全域性物件是global。
Node中全域性物件下有以下方法,可以在任何地方使用,global可以省略。
console.log() 在控制檯中輸出
setTimeout() 設定超時定時器
clearTimeout() 清除超時時定時器
setInterval() 設定間歇定時器
clearInterval() 清除間歇定時器
建立一個Web伺服器
新建一個app.js
//引入系統模組
const http = require('http');
//建立Web伺服器物件
const app = http.createServer();
//當客戶端傳送請求的時候
app.on('request', (req, res) => {
//響應
res.end('<h1>hello world</h1>');
});
//監聽埠
app.listen(3000);
console.log('伺服器已啟動,監聽3000埠,請訪問本機域名localhost:3000');
- 在node.js中建立web伺服器需要用到系統模組http,所以在系統模組上使用require模組引入http
- 使用createServer建立伺服器,返回值是網站伺服器物件
- node.js和JavaScript都是基於事件驅動的語言,比如JavaScript當用戶點選某個按鈕的時候做什麼事情。 node.js是當用戶接受什麼請求做什麼事情。
- 新增什麼事件呢?新增請求事件,也就是request事件(請求的意思)。新增請求的語法:伺服器.on
- on就是新增事件的意思,第一個引數是request請求,第二個引數是事件處理函式,當事件來的時候就會執行事件處理函式。
- 這個事件處理函式有兩個引數,第一個單詞req是request單詞的簡寫,代表請求物件,物件中儲存了請求的一些資訊,比如請求的地址、請求的ip;第二個單詞res是response單詞的簡寫,代表響應物件,使用這個物件的方法對客戶端發來的請求做出響應。
- 這個伺服器還要經過一個端口才能向外界進行服務,如何監聽埠呢?在網站app物件下有個方法叫listen,listen監聽的就是一個埠號。在node.js中習慣上將這個寫出3000
執行
開啟CMD或者PowerShell輸入以下命令執行app.js檔案
node aap.js
執行結果
伺服器顯示標識,利用標識響應不同的內容。
路由
路由是指客戶端請求地址與伺服器端程式程式碼的對應關係。簡單的說,就是請求什麼響應什麼。
在原先的基礎上增加路由功能,並優化程式碼
//1.引入系統模組http
//2.建立網站伺服器
//3.為網站伺服器物件新增請求事件
//4.實現路由功能
const http = require('http');
const url = require('url');
const app = http.createServer();
app.on('request', (req, res) => {
//1.獲取客戶端的請求方式
const method = req.method.toLowerCase();
//2.獲取請求地址
const pathname = url.parse(req.url).pathname;
//3.請求正常,伺服器新增字元編碼格式
res.writeHead(200, {
'content-type': 'text/html;charset=utf8'
});
//4.判斷客戶端輸入的域名,伺服器響應其內容
if (method == 'get') {
if (pathname == '/' || pathname == '/index') {
res.end('歡迎來到首頁');
} else if (pathname == '/list') {
res.end('歡迎來到列表頁')
} else {
res.end('您訪問的頁面不存在')
}
} else if (method == 'post') {
}
}).listen(3000);
console.log('伺服器啟動成功');