準備HTML模板文件index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>電影列表</h1>
<hr>
<table width="500" border="1" cellspacing="0" cellpadding="0">
<thead>
<tr>
<th width="200">名稱</th>
<th width="200">導演</th>
<th width="500">簡介</th>
</tr>
</thead>
<tbody>
<!-- 自定義模板語法,列表的渲染 -->
{%for {movies} %}
<tr>
<td>{{item.name}}</td>
<td>{{item.author}}</td>
<td>{{item.brief}}</td>
</tr>
{%endfor%}
</tbody>
</table>
</body>
</html>
創(chuàng)建服務(wù)器server.js 文件
//引入http和文件系統(tǒng)(均為node內(nèi)置模塊,無需安裝)
let http = require('http');
let fs = require('fs');
/**
* 模擬數(shù)據(jù)庫
*/
const MockDataBase = {
//定義一個查詢電影記錄的方法搁凸,返回一個movie對象
getMovie : function(){
let movie = {
name:'黑暗正義聯(lián)盟:天啟星戰(zhàn)爭',
brief:'正義聯(lián)盟集結(jié)地球上所有超級英雄一起對抗強大的反派達克賽德藕届。',
author:'馬特·皮特斯 Matt Peters'
};
return movie;
},
//定義一個查詢電影列表的方法方法,返回一個movie列表
getMovies : function(){
let movies = [{
name:'斗戰(zhàn)勝佛之大圣之淚',
brief:'成為斗戰(zhàn)勝佛的孫悟空竟被怨靈蠱惑赠摇,唐三藏遭遇滅頂之災(zāi)!危急關(guān)頭,孫悟空揪出怨靈源頭课竣,卻發(fā)現(xiàn)她竟是與自己有三百年緣分的天人界女神——“幸運星”!為了找出“幸運星”黑化的原因置媳,拯救唐三藏于樟,孫悟空踏上了一場回到過去之旅,卻最終流下了一滴眼淚拇囊。大圣之淚迂曲,為何而流,為誰而流寥袭?',
author:'鐘智行 Frankie Chung'
},{
name:'獵謊者',
brief:'三個月前路捧,某市發(fā)生了一起惡性綁架殺人案。三個月后传黄,兇手與被害人都死于車禍杰扫。初出茅廬的女警韓燁找到了案件的幸存者林超凡,向他求證案件發(fā)生的經(jīng)過膘掰。但隨著調(diào)查的深入章姓,韓燁發(fā)現(xiàn)林超凡的很多證詞都存在漏洞,再三逼問之下炭序,林超凡無奈坦白了另一個版本的故事啤覆,但案件真相遠沒有這么簡單,幾乎每個人都在說謊惭聂,而故事也開始不斷反轉(zhuǎn)窗声。',
author:'廉欣 Xin Lian'
},{
name:'天啟大爆炸',
brief:'《天啟大爆炸》以中國古代曾真實發(fā)生的神秘爆炸為原型,加以天馬行空的巧妙構(gòu)思辜纲,為觀眾解封至今困惑世人的隱秘真相笨觅。神秘機構(gòu)“夜行司”追蹤離奇謎團勇闖“無相城”,一場關(guān)乎百姓蒼生命運博弈就此展開耕腾。',
author:'黃羿 Yi Huang / 曾黎'
}];
return movies;
}
}
/**
* 實現(xiàn)一個簡單的模板引擎见剩,接收模板路徑和數(shù)據(jù)模型兩個參數(shù)。
* 原理就是讀取模板文件扫俺,根據(jù)自定義的模板語法解析苍苞,然后替換為模型數(shù)據(jù)
*/
function defaultTemplateEngine(path,model){
console.log('執(zhí)行模板引擎,渲染數(shù)據(jù)。')
fs.readFile(path,{encoding:"utf-8",flag:"r"},(err,data)=>{
if(err){
this.end(err);
}else{
/**
* 先使用正則匹配循環(huán)的變量和循環(huán)的內(nèi)容
* 也就是index.html模板中的
*
* movies 變量
* 和 以下循環(huán)的內(nèi)容
* <tr>
* <td>{{item.name}}</td>
* <td>{{item.author}}</td>
* <td>{{item.brief}}</td>
* </tr>
*
*/
let reg = /\{\%for \{(.*?)\} \%\}(.*?)\{\%endfor\%\}/igs;
while(result = reg.exec(data)){
let strKey = result[1].trim();
//通過key值獲取電影列表
let strValueArr = model[strKey];
let listStr = '';
/**
* 再循環(huán)電影列表羹呵,生成多條以下內(nèi)容骂际,并替換到HTML字符串
* <tr>
* <td>{{item.name}}</td>
* <td>{{item.author}}</td>
* <td>{{item.brief}}</td>
* </tr>
*/
strValueArr.forEach((item,index)=>{
listStr += replaceVar(result[2],{'item':item});
})
//替換到HTML字符串
data = data.replace(result[0],listStr);
}
/**
* 返回渲染完成的html內(nèi)容
* 因為回調(diào)函數(shù)使用的是匿名函數(shù),所在可以使用this對象冈欢,此處的this指向的是調(diào)用者歉铝,
* 此例中,調(diào)用者是http請求的響應(yīng)對象res凑耻,end是res對象中內(nèi)置的一個函數(shù)太示,此函數(shù)作用是結(jié)束請求,并發(fā)送響應(yīng)數(shù)據(jù)香浩。
*/
this.end(data);
}
})
}
/**
* 正則匹配每一條電影中的每個屬性
* <tr>
* <td>{{item.name}}</td>
* <td>{{item.author}}</td>
* <td>{{item.brief}}</td>
* </tr>
*/
function replaceVar(data,model){
let regex = /\{\{(.*?)\}\}/igs
let result;
while(result = regex.exec(data)){
let strKey = result[1].trim();
//替換
console.log(strKey)
let strValue = eval('model.' + strKey);
data = data.replace(result[0],strValue);
}
return data;
}
/**
* 實現(xiàn)一個簡單的模型引擎過濾器
* 此過濾器中向res對象追加了模板渲染引擎函數(shù)render类缤。
*/
function templateEngineFilter(req,res){
if(req.url == '/'){
console.log('執(zhí)行模板引擎過濾器,向響應(yīng)對象追加一個模板渲染引擎函數(shù)')
res.render = defaultTemplateEngine;
}
}
//創(chuàng)建一個服務(wù)
let server = http.createServer();
//服務(wù)監(jiān)聽請求
server.on('request',async function(req,res){
console.log('收到請求:' + req.url);
//執(zhí)行請求過濾器
templateEngineFilter(req,res);
//設(shè)置響應(yīng)類型及字符集編碼
res.setHeader('Content-Type','text/html;charset=utf-8')
//如果請求路徑是根路徑 ‘/’ 則返回電影信息頁面邻吭,否則返回404
if(req.url=='/'){
//從數(shù)據(jù)庫中獲取電影信息
let movies = await MockDataBase.getMovies();
//調(diào)用響應(yīng)對象的模板渲染函數(shù)呀非,將數(shù)據(jù)渲染到頁面
let model = {"movies":movies};
res.render('./index.html',model)
}else{
res.end('404!資源不存在镜盯。')
}
})
//服務(wù)監(jiān)聽80端口
server.listen(80,function(){
console.log('服務(wù)啟動成功。')
})
運行命令猖败,啟動服務(wù)
node server.js
server.gif