nodejs 开发,手把手开始第一个服务器程序(原生)
此文章為原生 nodejs??,僅做學(xué)習(xí)使用
想學(xué)習(xí) express 和 koa2 的小伙伴請(qǐng)繞路
此文章適合有HTML 和css 、js 基礎(chǔ)的小伙伴看哦
如果能幫到你,榮幸之至
文章純手打,如有紕漏歡迎下方留言
?
寫在前面:
127.0.0.1 : 回環(huán)地址,每一臺(tái)電腦都有該ip,指向當(dāng)前使用的電腦
nodejs 中的 js 與 瀏覽器中 js 的區(qū)別:
瀏覽器中 js :ECMAScript 核心 + DOM + BOM
Node 中的 js :ECMAScript 核心 + 全局成員 + 模塊系統(tǒng)(系統(tǒng)模塊、第三方模塊、自定義模塊)
全局成員: setTimeout、setInterval、console.log() 等。
注意 :這幾個(gè)名稱和功能雖然和瀏覽器中的一樣,但是是 Nodejs 自己實(shí)現(xiàn)的,與瀏覽器無(wú)關(guān)
?
安裝nodejs
中文網(wǎng):http://Nodejs.cn/
Nodejs 系統(tǒng)模塊是什么 :隨著 Nodejs 一起安裝
常用的系統(tǒng)模塊: fs、http、url、path 等一個(gè)模塊中包含了很多方法和屬性,可以幫助我們實(shí)現(xiàn)不同的功能
?
Node 創(chuàng)建 web 服務(wù)器
?
使用 HTTP 模塊搭建 web 服務(wù)器:
?
1、引入 http 模塊
創(chuàng)建一個(gè) js 文件,例如此處取名為 kiss.js 。
?
const http = require('http');?
2、創(chuàng)建服務(wù)器對(duì)象
?
const server = http.createServer();?
3、開(kāi)啟服務(wù)器
此處監(jiān)聽(tīng)了 3000 端口
?
server.listen(3000, () => {console.log('Server is running...'); });?
4、監(jiān)聽(tīng)瀏覽器請(qǐng)求并進(jìn)行處理
?
server.on('request', (req, res) => {// end方法能夠?qū)?shù)據(jù)返回給瀏覽器,瀏覽器會(huì)顯示該字符串res.end('Hello Nodejs'); });?
on :該方法用來(lái)監(jiān)聽(tīng)事件
參數(shù)1(此處的request):事件類型,request 代表瀏覽器請(qǐng)求事件
參數(shù)2 :回調(diào)函數(shù)。當(dāng)監(jiān)聽(tīng)到瀏覽器請(qǐng)求后出發(fā)的回調(diào)函數(shù),該函數(shù)中有兩個(gè)參數(shù)
第一個(gè)參數(shù)(此處的 req ):請(qǐng)求對(duì)象
第二個(gè)參數(shù)(此處的 res ):相應(yīng)對(duì)象
end 方法能夠?qū)?shù)據(jù)返回給瀏覽器,瀏覽器會(huì)顯示該字符串
遂,在 kiss.js 文件中,內(nèi)容如下:
?
//1. 導(dǎo)入 http 模塊 const http = require('http');//2. 創(chuàng)建服務(wù)器對(duì)象 const server = http.createServer();//3. 開(kāi)啟服務(wù)器 server.listen(3000, () => {console.log('Server is running...'); });//4. 監(jiān)聽(tīng)瀏覽器請(qǐng)求并進(jìn)行處理 server.on('request', (req, res) => {// end方法能夠?qū)?shù)據(jù)返回給瀏覽器,瀏覽器會(huì)顯示該字符串res.end('Hello Nodejs'); });?
在文件目錄中打開(kāi) cmd ,運(yùn)行命令 node .\kiss.js ,即可開(kāi)啟服務(wù)器:
?
打開(kāi)瀏覽器,在地址欄輸入??http://127.0.0.1:3000/?,會(huì)看到 res.end() 所返回的字符串
如圖
?
?
顯示頁(yè)面
?
服務(wù)器已經(jīng)搭建起來(lái)了,那么下一步就是如何在瀏覽器端展示頁(yè)面了
首先準(zhǔn)備一個(gè) HTML 文件,在 kiss.js 文件同級(jí)目錄下創(chuàng)建一個(gè) index.html 文件,準(zhǔn)備內(nèi)容如下
?
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>kisskiss</title><style>h2 {width: 800px;height: 60px;margin: 100px auto;line-height: 60px;text-align: center;color: white;background-image: linear-gradient(to right,rgb(255, 211, 218) 0%,rgb(132, 223, 132) 100%)}</style> </head> <body><h2>我是 kiss 首頁(yè)</h2> </body> </html>?
此時(shí)服務(wù)器文件 kiss.js 需要另一個(gè)模塊 :文件讀取模塊 ——> readFile
1、引入 fs 模塊
?
const fs = require('fs');?
2、調(diào)用 readFile 方法讀取文件內(nèi)容
?
fs.readFile('./index.html', 'utf-8', (err, data) => {if (err) {return console.log(err);}console.log(data); })?
參數(shù)1 : 要讀取的文件路徑,相對(duì)路徑和絕對(duì)路徑均可(推薦使用絕對(duì)路徑)
參數(shù)2 : 設(shè)置字符集, 常用的中文字符集有三種 : utf-8、 gb2312、 gbk?該參數(shù)是可選參數(shù),如果不設(shè)置該參數(shù),讀取內(nèi)容默認(rèn)是二進(jìn)制數(shù)據(jù)
參數(shù)3 : 讀取完成后觸發(fā)的回調(diào)函數(shù),該函數(shù)中有兩個(gè)參數(shù)? err 和 data
err : 錯(cuò)誤對(duì)象 -?如果讀取正確 :? err 為 null ;? 如果讀取失敗 :? err 為錯(cuò)誤對(duì)象 ;
data : 文件中的數(shù)據(jù)
在 congsole.log(data) 處,便可進(jìn)行對(duì)文件內(nèi)容的操作,data 整個(gè)是以字符串類型被取出
? 調(diào)整后 kiss.js 文件內(nèi)容如下 :
?
const http = require('http'); //1. 導(dǎo)入 http 模塊 const fs = require('fs'); //5. 導(dǎo)入/加載/引入 文件模塊//2. 創(chuàng)建服務(wù)器對(duì)象 const server = http.createServer();//3. 開(kāi)啟服務(wù)器 server.listen(3000, () => {console.log('Server is running...'); });//4. 監(jiān)聽(tīng)瀏覽器請(qǐng)求并進(jìn)行處理 server.on('request', (req, res) => {//6. 讀取文件fs.readFile('./index.html', 'utf-8', (err, data) => {if (err) {return console.log(err);}//7. end方法返回讀取的文件字符串,瀏覽器會(huì)顯示該文件內(nèi)容 res.end(data);})});?
在 cmd 中 Ctrl + C 退出之前啟動(dòng)的服務(wù)器,重新啟動(dòng)服務(wù)器?? node kiss.js?
在瀏覽器中刷新頁(yè)面?http://127.0.0.1:3000/?,可以看到準(zhǔn)備的 HTML 頁(yè)面已經(jīng)成功展示在瀏覽器中
如圖
?
?
Tips : 中文亂碼問(wèn)題
fs 的 readFile 函數(shù)中第二個(gè)參數(shù)可不寫,但是會(huì)造成頁(yè)面中文亂碼,另一個(gè)解決辦法是,使用 res(響應(yīng)對(duì)象)中的 setHeader 方法:
?
res.setHeader('content-type', 'text/html;charset=utf-8');?
?多個(gè)頁(yè)面時(shí)
?
再新建一個(gè)HTML頁(yè)面,index_2.html 內(nèi)容如下 :
?
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>第二個(gè)頁(yè)面</title><style>i {display: block;background-color: pink;width: 300px;height: 50px;border-radius: 15px;text-align: center;line-height: 50px;}</style> </head> <body><i>這是第二個(gè)頁(yè)面</i> </body> </html>?
此時(shí)問(wèn)題是,如何才能在輸入不同的網(wǎng)址的時(shí)候,顯示不同的兩個(gè)頁(yè)面?
解決辦法,修改 kiss.js 代碼如下 :
?
const http = require('http'); //1. 導(dǎo)入 http 模塊 const fs = require('fs'); //5. 導(dǎo)入/加載/引入 文件模塊//2. 創(chuàng)建服務(wù)器對(duì)象 const server = http.createServer();//3. 開(kāi)啟服務(wù)器 server.listen(3000, () => {console.log('Server is running...'); });//4. 監(jiān)聽(tīng)瀏覽器請(qǐng)求并進(jìn)行處理 server.on('request', (req, res) => {//6. req對(duì)象的url屬性中保存了當(dāng)前請(qǐng)求的url地址const url = req.url//7.判斷不同url,返回不同頁(yè)面到瀏覽器端進(jìn)行展示if (url === '/') {//8. 讀取文件index.htmlfs.readFile('./index.html', 'utf-8', (err, data) => {if (err) {return console.log(err);}// end方法返回讀取的文件字符串,瀏覽器會(huì)顯示該文件內(nèi)容 res.end(data);})} else if (url === '/index_2') {//8. 讀取文件index_2.htmlfs.readFile('./index_2.html', 'utf-8', (err, data) => {if (err) {return console.log(err);}// end方法返回讀取的文件字符串,瀏覽器會(huì)顯示該文件內(nèi)容 res.end(data);})} });?
重啟服務(wù)器,在瀏覽器地址欄輸入?http://127.0.0.1:3000?,依舊顯示原來(lái) index.html 頁(yè)面的內(nèi)容
在地址欄輸入?http://127.0.0.1:3000/index_2?,顯示新的 index_2.html 頁(yè)面的內(nèi)容,如下 :
?
注意: url屬性中保存的地址是沒(méi)有 協(xié)議、IP、端口號(hào),并且以 / 開(kāi)頭的地址
http://127.0.0.1:3000? ? ?===>? ? /
http://127.0.0.1:3000/index_2? ??===>? ? ?/index_2
?
靜態(tài)資源加載
?
上面已經(jīng)初步體驗(yàn)了一個(gè)服務(wù)器是怎樣跑起來(lái)的,但是!上面只有一個(gè) html 文件,并且它的樣式是直接包含在 html 文件中的,如果一個(gè) HTML 文件內(nèi)引入了它的資源文件呢? 比如 css 和 js 文件。
修改文件結(jié)構(gòu)目錄如下 :
?
?
index.html 頁(yè)面內(nèi)容 :
?
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>kisskiss</title><link rel="stylesheet" type="text/css" href="../public/css/index.css"><script type="text/javascript" src="../public/js/index.js"></script> </head> <body><h2>我是 kiss 首頁(yè)</h2> </body> </html>?
將原來(lái) HTML 文件中的 css 資源單獨(dú)抽取出來(lái)寫入 index.css 文件中,index.css 文件內(nèi)容 :
?
h2 {width: 800px;height: 60px;margin: 100px auto;line-height: 60px;text-align: center;color: white;background-image: linear-gradient(to right,rgb(255, 211, 218) 0%,rgb(132, 223, 132) 100%) }?
index.js 文件內(nèi)容 :
?
alert('this is kiss.js');?
kiss.js 文件內(nèi)容 :
?
const http = require('http'); //1. 導(dǎo)入 http 模塊 const fs = require('fs'); //5. 導(dǎo)入/加載/引入 文件模塊//2. 創(chuàng)建服務(wù)器對(duì)象 const server = http.createServer();//3. 開(kāi)啟服務(wù)器 server.listen(3000, () => {console.log('Server is running...'); });//4. 監(jiān)聽(tīng)瀏覽器請(qǐng)求并進(jìn)行處理 server.on('request', (req, res) => {//6. req對(duì)象的url屬性中保存了當(dāng)前請(qǐng)求的url地址const url = req.url//7.判斷不同url,返回不同頁(yè)面到瀏覽器端進(jìn)行展示if (url === '/') {//8. 讀取文件index.htmlfs.readFile('./view/index.html', 'utf-8', (err, data) => {if (err) {return console.log(err);}// end方法返回讀取的文件字符串,瀏覽器會(huì)顯示該文件內(nèi)容 res.end(data);})} });?
啟動(dòng)服務(wù)器,主頁(yè)一直處于加載狀態(tài)
按下鍵盤 f12 ,或者單擊鼠標(biāo)右鍵 → 檢查 → 選擇 network :
?
?
可以看到 index.css 和 index.js 文件的狀態(tài)(status)顯示為 pending?
服務(wù)器發(fā)起了對(duì) index.css 和 index.js 文件的請(qǐng)求,但是卻一直未得到服務(wù)器的響應(yīng)
來(lái)分析一下此處的原理 :
?
?
1、瀏覽器中輸入請(qǐng)求地址 http:127.0.0.1:3000,按下回車發(fā)送請(qǐng)求
2、服務(wù)器根據(jù)請(qǐng)求信息的 url (此時(shí)為 "/")找到 index.html ,并將內(nèi)容返回給瀏覽器
3、瀏覽器接收到服務(wù)器返回的內(nèi)容,開(kāi)始對(duì) index.html 進(jìn)行解析,當(dāng)解析到 link 標(biāo)簽和 script 標(biāo)簽時(shí),再次請(qǐng)求服務(wù)器,想要獲取 index.css 和 index.js 文件,可是我們的服務(wù)器代碼中,并沒(méi)有寫針對(duì)這兩個(gè)文件的內(nèi)容,所以也就不會(huì)返回這兩個(gè)文件的內(nèi)容,服務(wù)器就會(huì)一直處于等待狀態(tài),直到超時(shí)報(bào)錯(cuò)。
接下來(lái)我們修改一下 kiss.js 文件,內(nèi)容如下 :
?
const http = require('http'); //1. 導(dǎo)入 http 模塊 const fs = require('fs'); //5. 導(dǎo)入/加載/引入 文件模塊//2. 創(chuàng)建服務(wù)器對(duì)象 const server = http.createServer();//3. 開(kāi)啟服務(wù)器 server.listen(3000, () => {console.log('Server is running...'); });//4. 監(jiān)聽(tīng)瀏覽器請(qǐng)求并進(jìn)行處理 server.on('request', (req, res) => {//6. req對(duì)象的url屬性中保存了當(dāng)前請(qǐng)求的url地址const url = req.url//7.判斷不同url,返回不同頁(yè)面到瀏覽器端進(jìn)行展示if (url === '/') {//8. 讀取文件index.htmlfs.readFile('./view/index.html', 'utf-8', (err, data) => {if (err) {return console.log(err);}// end方法返回讀取的文件字符串,瀏覽器會(huì)顯示該文件內(nèi)容 res.end(data);})} else if (url === '/index_2') {//8. 讀取文件index_2.htmlfs.readFile('./view/index_2.html', 'utf-8', (err, data) => {if (err) {return console.log(err);}// end方法返回讀取的文件字符串,瀏覽器會(huì)顯示該文件內(nèi)容 res.end(data);})} else if(url.startsWith('/public')) {//8. 讀取index.html文件的靜態(tài)資源文件fs.readFile('.'+url, 'utf-8', (err, data) => {if (err) {return console.log(err);}// end方法返回讀取的文件字符串,瀏覽器會(huì)顯示該文件內(nèi)容 res.end(data);})} });?
分析?:因?yàn)殪o態(tài)資源文件全部被放到了同一個(gè) public 文件夾下,所以我們用一個(gè) else if 分支來(lái)處理就可以了
index.css 文件的 req(請(qǐng)求對(duì)象)的 url 屬性,值為 '/public/css/index.css'
index.js 文件的 req(請(qǐng)求對(duì)象)的 url 屬性,值為 '/public/js/index.js'
所以我們判斷,當(dāng) url 以 '/public' 開(kāi)頭的時(shí)候,便將 fs 的 readFile 方法的第一個(gè)參數(shù)(文件路徑)拼接成相對(duì)路徑加上 url 的形式
?
? 刷新頁(yè)面,可以看到彈出 js 文件內(nèi)容:
?
?
點(diǎn)擊確定后可以看到帶有 css 樣式的頁(yè)面,成功顯示!
?
?
?
?
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/yummylucky/p/10367065.html
總結(jié)
以上是生活随笔為你收集整理的nodejs 开发,手把手开始第一个服务器程序(原生)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: struts2和springmvc的区别
- 下一篇: FastThreadLocal