一文詳解Node.js服務(wù)器動(dòng)態(tài)資源處理
一、node.js服務(wù)器動(dòng)態(tài)資源處理與靜態(tài)資源處理的區(qū)別
靜態(tài)與動(dòng)態(tài)服務(wù)器主要區(qū)別于是否讀取數(shù)據(jù)庫(kù),若然在數(shù)據(jù)庫(kù)中的資料處理中將數(shù)據(jù)轉(zhuǎn)換成可取用格式的結(jié)構(gòu),也就是說(shuō)把對(duì)象轉(zhuǎn)化為可傳輸?shù)淖止?jié)序列過(guò)程稱(chēng)為序列化,反之則為反序列化。
簡(jiǎn)單來(lái)說(shuō),它比起靜態(tài)資源較復(fù)雜,因?yàn)樗鼤?huì)隨用戶(hù)不同、響應(yīng)內(nèi)容不同而不斷產(chǎn)生變化
二、什么是動(dòng)態(tài)資源處理
以JSON與JS為例,JSON.stringify()對(duì)數(shù)據(jù)序列化,JSON.parse()對(duì)數(shù)據(jù)反序列化。動(dòng)態(tài)處理也就是對(duì)數(shù)據(jù)進(jìn)行重新排序來(lái)讀寫(xiě)數(shù)據(jù)庫(kù),讀取反序列化,寫(xiě)入序列化。
三、處理動(dòng)態(tài)資源的方法
將頁(yè)面內(nèi)容動(dòng)態(tài)化。使用到第三方模塊——>模板引擎 去動(dòng)態(tài)將我的數(shù)據(jù)嵌入到我的網(wǎng)頁(yè)中去。
什么是模板引擎?見(jiàn) 文末補(bǔ)充內(nèi)容
四、代碼示例
(1)我們將首頁(yè)、登錄、注冊(cè)三個(gè)html靜態(tài)頁(yè)面和用戶(hù)列表users.html寫(xiě)在views這個(gè)大文件夾下。css樣式和images圖片放入public這個(gè)大文件夾下。創(chuàng)建一個(gè)data大文件夾,data下面建一個(gè)user.json文件來(lái)專(zhuān)門(mén)存儲(chǔ)用戶(hù)數(shù)據(jù)
簡(jiǎn)單寫(xiě)一下首頁(yè)、注冊(cè)、登錄頁(yè)面的html靜態(tài)頁(yè)面的樣式。此處省略。具體見(jiàn) 詳解Node.js服務(wù)器靜態(tài)資源處理

動(dòng)態(tài)資源處理具體表現(xiàn)就是我的用戶(hù)列表渲染功能(users.html)和我的不同錯(cuò)誤提示功能(404.html)。
用戶(hù)列表渲染功能可以將我的user.json里面注冊(cè)成功的用戶(hù)數(shù)據(jù)渲染到我服務(wù)器用戶(hù)列表頁(yè)面
users.html 用戶(hù)列表:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用戶(hù)列表</title>
<link rel="stylesheet" href="../public/css/main.css" rel="external nofollow" >
</head>
<body>
<h1>用戶(hù)列表</h1>
<img src="../public/images/01.png" alt=""><br>
<ul>
<!-- 循環(huán)li -->
<% for(let username in users){ %>
<li>
<!-- 取出屬性名和密碼這個(gè)屬性值,放入li里面 -->
<%=username %> : <%=users[username] %>
</li>
<% } %>
</ul>
</body>
</html>404.html 不同錯(cuò)誤提示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>404</title>
</head>
<style>
body {
background-color:pink;
}
</style>
<body>
<h1>
<!-- 定義模板 -->
<%= msg %>
</h1>
</body>
</html>(2)在我的測(cè)試代碼的終端 npm install underscore -save安裝underscore渲染模板引擎 、npm install querystring安裝querystring查詢(xún)模塊

(3) 測(cè)試代碼如下:
const http = require('http');
const fs = require('fs');
const path = require('path');
const url = require('url');
// 聲明一個(gè)專(zhuān)門(mén)存放所有用戶(hù)的變量
var users;
// 導(dǎo)入查詢(xún)參數(shù)的模塊
const querystring = require('querystring');
// 導(dǎo)入underscore渲染模板
const _ =require('underscore');
//使用underscore渲染模板
function render(data){
// 讀取模板內(nèi)容
let temp=fs.readFileSync(path.join(__dirname,'views/404.html'));
// 獲取渲染函數(shù)
let compiled=_.template(temp.toString());
// 渲染模板
return compiled(data);
}
//創(chuàng)建服務(wù)器
const server = http.createServer();
//讀取文件。讀取user.json存放用戶(hù)數(shù)據(jù)的文件
fs.readFile(path.join(__dirname, 'data/users.json'), (err, data) => {
if (err) {
users = {};
} else {
users = JSON.parse(data.toString()); //如果讀取正確就將讀到的內(nèi)容轉(zhuǎn)換為一個(gè)對(duì)象存到users里
}
})
//服務(wù)器做出請(qǐng)求響應(yīng)
server.on('request', (req, res) => {
let objurl = url.parse(req.url); //將url轉(zhuǎn)為一個(gè)對(duì)象才能獲取到它的pathname
let pathname = objurl.pathname;
// 對(duì)pathname做處理
if (pathname.startsWith('/public')) {
// 找到當(dāng)前項(xiàng)目文件夾,再將相對(duì)路徑轉(zhuǎn)為絕對(duì)路徑
let p = path.join(__dirname, pathname);
fs.readFile(p, (err, data) => {
if (err) {
res.end(render({msg:'訪(fǎng)問(wèn)的文件不存在'})); //可以使用中文,因?yàn)楝F(xiàn)在是html頁(yè)面去顯示的
} else {
res.end(data);
}
})
} else if (pathname == '/' || pathname == '/home') {
let p = path.join(__dirname, 'views/index.html');
fs.readFile(p, (err, data) => {
if (err) {
res.end(render({msg:'訪(fǎng)問(wèn)的文件不存在'}));
} else {
res.end(data);
}
})
} else if (pathname == '/regist') { //建一個(gè)文件夾data專(zhuān)門(mén)來(lái)儲(chǔ)存數(shù)據(jù) 里面建一個(gè)users.json的文件
let p = path.join(__dirname, 'views/regist.html');
fs.readFile(p, (err, data) => {
if (err) {
res.end(render({msg:'訪(fǎng)問(wèn)的文件不存在'}));
} else {
res.end(data);
}
})
} else if (pathname == '/login') {
let p = path.join(__dirname, 'views/login.html');
fs.readFile(p, (err, data) => {
if (err) {
res.end(render({msg:'訪(fǎng)問(wèn)的文件不存在'}));
} else {
res.end(data);
}
})
} else if (pathname == '/doRegist') {
// Node.js 的 querystring 模塊用于解析和格式化 URL 查詢(xún)字符串:
// 1. 將字符串參數(shù)解析成對(duì)象
// querystring.parse(url)
// 2. 將對(duì)象參數(shù)解析成字符串
// querystring.stringify(urlObject)
let query = querystring.parse(objurl.query);
let username = query.username;
let password = query.password;
if (users[username]) {
res.end(render({msg:'用戶(hù)名已存在,不能注冊(cè)!'}));
} else {
//因?yàn)閡sers里面是一個(gè)對(duì)象。所以只能屬性名=值的形式。故屬性名 = 密碼(密碼相當(dāng)于這個(gè)屬性名對(duì)應(yīng)的屬性值)
users[username] = password;
//利用JSON.stringify(users)將users對(duì)象轉(zhuǎn)為字符串重新寫(xiě)到文件里去
fs.writeFile(path.join(__dirname, 'data/users.json'), JSON.stringify(users), (err) => {
if (err) {
res.end(render({msg:'注冊(cè)失敗'}));
} else {
res.end(render({msg:'注冊(cè)成功'}));
}
})
}
} else if (pathname == '/doLogin') {
let query = querystring.parse(objurl.query);
let username = query.username;
let password = query.password;
// 判斷users的用戶(hù)名和密碼有無(wú)
if (users[username] && users[username] == password) { //用戶(hù)名 && 密碼
res.writeHead(200, { 'Content-Type': 'text/html;charset=utf-8' });
res.end(render({msg:'登錄成功'}));
} else {
res.writeHead(502, { 'Content-Type': 'text/html;charset=utf-8' });
res.end(render({msg:'用戶(hù)名或密碼錯(cuò)誤,登錄失敗'}));
}
} else if (pathname == '/list') {
let p=path.join(__dirname,'views/users.html');
fs.readFile(p,(err,data)=>{
if(err){
res.end(render({msg:'訪(fǎng)問(wèn)的文件不存在'}));
}else{
//獲得渲染函數(shù)
let compiled=_.template(data.toString());
// 調(diào)用渲染函數(shù)來(lái)生成html內(nèi)容
let html=compiled({users:users}); //我們?cè)谀0謇锶〉氖莡sers的屬性,所以不能簡(jiǎn)寫(xiě)成users,而是users:users
res.end(html);
}
})
}
});
server.listen(3000, '127.0.0.1', () => {
console.log('Server is running at http://127.0.0.1:3000');
})(4)結(jié)果顯示
當(dāng)我的用戶(hù)數(shù)據(jù)已被注冊(cè)時(shí):

動(dòng)態(tài)顯示我的404.html頁(yè)面

我完成用戶(hù)注冊(cè)時(shí),我點(diǎn)擊用戶(hù)列表,顯示結(jié)果如下:


綜上所述,相比我的靜態(tài)資源處理而言,我的動(dòng)態(tài)資源處理就相對(duì)效率較高,對(duì)于不同的錯(cuò)誤信息,我可以直接使用我的404.html模板,直接在我的運(yùn)行代碼中顯示 res.end(render({msg:'錯(cuò)誤內(nèi)容'})); 并且我可以直接使用用戶(hù)數(shù)據(jù)模板user.html使用<% %> 執(zhí)行javascript代碼??梢灾苯釉谖曳?wù)器端頁(yè)面展示我的所有成功注冊(cè)的用戶(hù)數(shù)據(jù)。化繁為簡(jiǎn)。
五、知識(shí)補(bǔ)充
node.js 什么是模板引擎
在 Web 開(kāi)發(fā)中,數(shù)據(jù)的呈現(xiàn)通常是基于 HTML 和 CSS 的,而數(shù)據(jù)的變化又是非常頻繁的,需要根據(jù)數(shù)據(jù)動(dòng)態(tài)生成 HTML 標(biāo)記。手動(dòng)拼接 HTML 標(biāo)記顯然是一種非常低效的方式,不僅容易出錯(cuò),而且難以維護(hù)。使用,我們使用到了模板引擎來(lái)解決這一問(wèn)題。
模板引擎概念
模板引擎是一種將數(shù)據(jù)和模板結(jié)合起來(lái)生成最終結(jié)果的工具。它將一個(gè)模板和一個(gè)數(shù)據(jù)對(duì)象轉(zhuǎn)為輸入,通過(guò)模板解析和渲染生成最終的結(jié)果。通俗來(lái)說(shuō),模板引擎就是用來(lái)生成html等標(biāo)記的工具。可以分解為兩部分:
1.模板:一個(gè)模子(結(jié)構(gòu))。依據(jù)不同數(shù)據(jù)套不同的邏輯
2.引擎:一個(gè)處理器(編譯、運(yùn)行),最后渲染出HTML代碼
模板引擎作用
模板引擎在Web開(kāi)發(fā)中扮演著重要角色,其主要作用包括:
(1)界面與數(shù)據(jù)分離
(2)業(yè)務(wù)代碼與邏輯代碼分離
(3) 生成特定格式的文檔
(4)支持邏輯控制語(yǔ)句
(5)模板繼承
(6)提高開(kāi)發(fā)效率
常用的模板引擎:
(1)underscore
(2)art-template
(3)ejs
(4)jade
下面,我們來(lái)具體介紹常用的underscore模板引擎:
underscore模板引擎:
(1)安裝underscore
npm install underscore —save
(2)導(dǎo)入underscore
var_=require('underscore')
(3)補(bǔ)充:依賴(lài)項(xiàng)問(wèn)題
如上述的安裝underscore后面要接 —save,意思是將模塊安裝到項(xiàng)目目錄下,并在package文件的dependencies節(jié)點(diǎn)寫(xiě)入依賴(lài)。
-g 的意思是將模塊安裝到全局,具體安裝到磁盤(pán)哪個(gè)位置,要看 npm config prefix 的位置。
-save-dev 的意思是將模塊安裝到項(xiàng)目目錄下,并在package文件的devDependencies節(jié)點(diǎn)寫(xiě)入依賴(lài)。
(4)在underscore模板文件中制定渲染規(guī)則
<%= %> 插入數(shù)據(jù)
eg:
<%=name%>
<% %> 執(zhí)行javascript代碼(一定要遵循js語(yǔ)法規(guī)則)
eg:
<%
for(let i=0;;i<3;i++){...}
%>
(5)使用underscore渲染模板
獲取渲染函數(shù)
var compiled=_.template(data)
注意 _是模板引擎的對(duì)象,data是模板文件內(nèi)容
渲染數(shù)據(jù)生成html內(nèi)容
var htmlstr=compiled(dataObj)
注意 dataObj是模板文件所需數(shù)據(jù)對(duì)象
到此這篇關(guān)于一文詳解Node.js服務(wù)器動(dòng)態(tài)資源處理的文章就介紹到這了,更多相關(guān)Node.js服務(wù)器動(dòng)態(tài)資源處理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Node.js全局對(duì)象Global的實(shí)現(xiàn)
在Nodejs下全局變量和全局函數(shù)都是可以使用global來(lái)訪(fǎng)問(wèn)到的,本文主要介紹了Node.js全局對(duì)象Global的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2023-12-12
Win7系統(tǒng)中如何安裝高版本的NodeJS(親測(cè)有效!)
Node.js是基于Chrome V8引擎的JavaScript運(yùn)行環(huán)境,能夠使JavaScript在服務(wù)器端運(yùn)行,這篇文章主要給大家介紹了關(guān)于Win7系統(tǒng)中如何安裝高版本的NodeJS的相關(guān)資料,需要的朋友可以參考下2023-12-12
Node.js中利用js-xlsx處理xlsx文件的實(shí)現(xiàn)
js-xlsx庫(kù)是目前Github上star數(shù)量最多的處理Excel的庫(kù),本文介紹用 Node.js中的js-xls庫(kù)來(lái)處理Excel文件,具有一定的參考價(jià)值,感興趣的可以了解一下2023-10-10
IDE升級(jí)重啟后Next.js?dev起不來(lái)kill無(wú)效的真正原因及排查過(guò)程
這篇文章主要介紹了IDE升級(jí)重啟后Next.js?dev起不來(lái)kill無(wú)效的真正原因及排查過(guò)程,強(qiáng)調(diào)了排查命令和習(xí)慣的重要性,適用于VSCode/WebStorm等同類(lèi)場(chǎng)景,需要的朋友可以參考下2026-05-05
nvm版本導(dǎo)致npm?install報(bào)錯(cuò)Unexpected?token?'.'的解決辦法
最近做項(xiàng)目遇到npm install 的問(wèn)題,下面這篇文章主要給大家介紹了關(guān)于nvm版本導(dǎo)致npm?install報(bào)錯(cuò)Unexpected?token?'.'的解決辦法,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下2022-07-07
node.js開(kāi)發(fā)中使用Node Supervisor實(shí)現(xiàn)監(jiān)測(cè)文件修改并自動(dòng)重啟應(yīng)用
這篇文章主要介紹了node.js開(kāi)發(fā)中使用Node Supervisor實(shí)現(xiàn)監(jiān)測(cè)文件修改并自動(dòng)重啟應(yīng)用的功能,從而避免大量重復(fù)的CTRL+C終止程序動(dòng)作,需要的朋友可以參考下2014-11-11
基于socket.io和node.js搭建即時(shí)通信系統(tǒng)
socket.IO是一個(gè)websocket庫(kù),包括了客戶(hù)端的js和服務(wù)器端的nodejs。官方地址:http://socket.io2014-07-07

