Node.js 實現靜態網站功能
- 使用http模塊初步實現服務器功能
const http = require('http');
let server = http.createServer();
server.on('request', (req, res) => {
res.end("hello world"); //訪問瀏覽器地址127.0.0.1:3000在網頁上顯示hello world
});
server.listen(3000); //設置監聽的端口
- 實現靜態服務器功能
- 實現請求路徑的分發
- req對象是Class: http.IncomingMessage的實例對象,可以在該類下查看相關方法的使用
- res對象是Class: http.ServerResponse的實例對象
- 實現圖片等其他資源的訪問需要根據文件類型設置響應類型
- 實現請求路徑的分發
const http = require('http');
const fs = require('fs');
const path = require('path');
const mime = require('./lib/mime.json'); //用於通過文件後綴設置響應頭
//用於讀取指定路徑的文件內容並返回到瀏覽器
let readFile = (dpath, res) => {
fs.readFile(path.join(__dirname, 'www', dpath), (err, fileContent) => {
if (err) {
//第一個參數爲響應狀態碼
res.writeHead(404, {
'Content-Type': 'text/plain;charset=utf8'//設置響應類型和編碼,解決亂碼
})
res.end("404頁面找不到了");//終止響應,不可以多次寫入
} else {
let dtype = "text/html"; //設置默認類型
let ext = path.extname(dpath);
if (mime[ext]) {
dtype = mime[ext]; //通過文件後綴獲取對應類型
}
if (dtype.startsWith('text')) {
dtype += ';charset=utf8'; //響應內容爲文本的時候設置編碼
}
res.writeHead(200, {
'Content-Type': dtype
})
res.end(fileContent);
}
})
}
http.createServer((req, res) => {
//res.end(req.url); //獲取到端口之後的路徑
if (req.url.startsWith('/index')) {
//res.write("訪問了"); //向客戶端響應內容,可以寫入多次
readFile(req.url, res);
} else if (req.url.startsWith('/list')) {
readFile(req.url, res);
} else if (req.url.startsWith('/detail')) {
readFile(req.url, res);
}
//以上的if判斷可以省略,直接調用 readFile(req.url, res); 即可
}).listen(3000, '192.168.1.104', () => { //該ip爲本電腦連接wifi後的IP地址,可省略則默認爲127.0.0.1
console.log("服務running");
})
參數傳遞與獲取
- get參數獲取
- url.parse(urlString) 將url字符串轉爲對象,第二個參數可傳入true表示將對參數url進行querystring.parse解析
- url.format(urlObject) 將url對象轉爲字符
const url = require('url');
let myURL =
url.parse('http://user:[email protected]:8080/p/a/t/h?query=string#hash');
console.log(myURL);
url.format(myURL);
/*
Url {
protocol: 'http:', //協議
slashes: true, //當Url協議中的冒號後面包含雙斜槓/則爲true
auth: 'user:pass', //用戶名密碼認證信息
host: 'sub.example.com:8080', //包含端口號的域名
port: '8080', //端口
hostname: 'sub.example.com', //不包含端口號的域名
hash: '#hash', //錨點
search: '?query=string', //問號以及所有參數
query: 'query=string', //去掉問號後的所有參數
pathname: '/p/a/t/h', //域名後之後不包含參數的路徑
path: '/p/a/t/h?query=string', //包含參數的路徑
href: 'http://user:[email protected]:8080/p/a/t/h?query=string#hash' //url完整字符串
}
*/
- get請求處
const http = require('http');
const ss = require('./staticServer.js');
const path = require('path');
const url = require('url');
http.createServer((req, res) => {
let urlObj = url.parse(req.url, true);
res.end(urlObj.query.username + '-' + urlObj.query.pass);
}).listen(3000, () => {
console.log("服務running");
})
//測試:http://127.0.0.1:3000/index.html?username=hym&pass=12
- post參數獲取
- querystring.parse(urlstr) 將字符串轉爲對象,當多個參數一樣時,將參數的值放入數組中
- querystring.stringify(obj) 將對象中的參數拼接成字符串(自動拆分數組)
const querystring = require('querystring');
let param = 'foo=bar&abc=xyz&abc=123';
let obj = querystring.parse(param);
console.log(obj);
/* {
foo: 'bar',
abc: ['xyz', '123']
} */
let str = querystring.stringify(obj);
console.log(str);
/* foo=bar&abc=xyz&abc=123 */
- post請求處
const http = require('http');
const querystring = require('querystring');
http.createServer((req, res) => {
if (req.url.startsWith('/login')) {
let allData = '';
req.on('data', (chunk) => {
allData += chunk; //將接受的數據拼接完整
});
req.on('end', () => {
console.log(allData);
let obj = querystring.parse(allData);
res.end(obj.username + "-" + obj.pass);
})
}
}).listen(3000, () => {
console.log("服務running···");
})
//測試:使用chrome插件postman模擬發送post請求,參數格式選擇www-form-urlencoded
動態網站
創建服務器實現動態網站的效果
- 路由 即請求路徑+請求方式
- .tpl 模板文件
//visual studio code中將.tpl文件識別爲html文件並高亮
// 將設置放入file --> preferences --> settings
//-->Text Editor --> Files --> Edit in settings.json文件中以覆蓋默認設置
{
"files.associations": {
"*.tpl":"html"
}
}
<!--創建模板文件query用於輸入關鍵字、result.tpl用於存放查詢的結果-->
<body>
<table>
<tr>
<th>英文</th>
<th>中文</th>
<th>應用場景</th>
</tr>
<tr>
<td>$$english$$</td>
<td>$$chinese$$</td>
<td>$$application$$</td>
</tr>
</table>
</body>
- node服務(需要準備虛擬數據search.json文件)
const http = require('http');
const path = require('path');
const fs = require('fs');
const querystring = require('querystring');
const virtualData = require('./virtualData/search.json');
http.createServer((req, res) => {
//查詢入口 /query
if (req.url.startsWith('/query') && req.method == 'GET') {
fs.readFile(path.join(__dirname, 'www/view', 'query.tpl'), 'utf8', (err, content) => {
if (err) {
res.writeHead(500, {
'Content-Type': 'text/plain;charset=utf8'
});
res.end("500服務器錯誤!")
}
res.end(content);
})
} else if (req.url.startsWith('/result')) {
let allData = '';
req.on('data', (chunk) => {
allData += chunk;
});
req.on('end', () => {
let obj = querystring.parse(allData);
let result = virtualData[obj.key];
fs.readFile(path.join(__dirname, 'www/view', 'result.tpl'), 'utf8', (err, content) => {
if (err) {
res.writeHead(500, {
'Content-Type': 'text/plain;charset=utf8'
});
res.end("500服務器錯誤!")
}
//進行數據渲染
content = content.replace('$$english$$', result.english);
content = content.replace('$$chinese$$', result.chinese);
content = content.replace('$$application$$', result.application);
//或者使用模板引擎art-template
//let html = template(path.join(__dirname, 'www/view', 'result.art'), result)
res.end(content);
})
})
}
}).listen(3000, () => {
console.log("服務running···")
})
- 案例:實現登錄驗證功能
const http = require('http');
const querystring = require('querystring');
const ss = require('./staticServer.js');
http.createServer((req, res) => {
//啓動靜態資源服務
if (req.url.startsWith('/www')) {
ss.staticServer(req, res, __dirname);
}
//啓動動態服務
if (req.url.startsWith('/login')) {
//get請求處理
if (req.method == 'GET') {
}
//post請求處理
if (req.method == 'POST') {
let allData = '';
req.on('data', (chunk) => {
allData += chunk;
});
req.on('end', () => {
let obj = querystring.parse(allData);
res.writeHead(500, {
'Content-Type': 'text/plain;charset=utf8' //防止中文亂碼
});
if (obj.username == 'admin' && obj.pass == 'root') {
res.end('登錄成功');
} else {
res.end('登錄失敗');
}
});
}
}
}).listen(3000, () => {
console.log("服務running···")
})
模板引擎 art-template
- 理解模板引擎本質
- 引擎基本使用
const path = require('path');
var template = require('art-template');
//使用方式一:創建好.art文件
var html = template(path.join(__dirname, '../mytpl.art'), {
user: {
name: 'aui'
}
});
console.log(html);
//使用方式二:字符串形式
/* let tpl = '<ul>{{each list value index}}<li>{{index}}{{value}}</li>{{/each}}</ul>';
let render = template.compile(tpl);
let ret = render({
list: ['english', 'math', 'chinese']
});
console.log(ret); */
//使用方式三:簡單化
/* let tpl = '<ul>{{each list}}<li>{{$index}}{{$value}}</li>{{/each}}</ul>';
let ret = template.render(tpl, {
list: ['english', 'math', 'chinese']
});
console.log(ret); */