Node核心API
1.Buffer對象
<body>
<!--
0.準備知識
0.1計算機只能識別0和1(因為計算機只認識通電和斷電兩種狀態),
0.2所有存儲在計算機上的數據都是0和1組成的(數據越大0和1就越多)
0.3計算機中的度量單位
1 B(Byte字節) = 8 bit(位)
// 00000000 就是一個字節
// 111111111 也是一個字節
// 10101010 也是一個字節
// 任意8個 0或1的組合都是一個字節
1 KB = 1024 B
1 MB = 1024KB
1 GB = 1024MB
1.什么是Buffer?
Buffer是NodeJS全局對象上的一個類, 是一個專門用于存儲字節數據的類
NodeJS提供了操作計算機底層API, 而計算機底層只能識別0和1,
所以就提供了一個專門用于存儲字節數據的類
2.如何創建一個Buffer對象
2.1創建一個指定大小的Buffer
Buffer.alloc(size[, fill[, encoding]])
2.2根據數組/字符串創建一個Buffer對象
Buffer.from(string[, encoding])
3.Buffer對象本質
本質就是一個數組
-->
</body>
js代碼
let buf = Buffer.alloc(5);
console.log(buf); // <Buffer 00 00 00 00 00>
// 注意點: 通過console.log();輸出Buffer. 會自動將存儲的內容轉換成16進制再輸出
let buf1 = Buffer.alloc(5, 17);
console.log(buf1);
let buf2 = Buffer.from("abc");
console.log(buf2); // <Buffer 61 62 63>
let buf3 = Buffer.from([1, 3, 5]);
console.log(buf3);
// console.dir(buf);
buf[0] = 6;
console.log(buf3);
2.Buffer實例方法
<body>
<!--
1.將二進制數據轉換成字符串
返回: <string> 轉換后的字符串數據。
buf.toString();
2.往Buffer中寫入數據
string <string> 要寫入 buf 的字符串。
offset <integer> 開始寫入 string 之前要跳過的字節數。默認值: 0。
length <integer> 要寫入的字節數。默認值: buf.length - offset。
encoding <string> string 的字符編碼。默認值: 'utf8'。
返回: <integer> 已寫入的字節數。
buf.write(string[, offset[, length]][, encoding])
3.從指定位置截取新Buffer
start <integer> 新 Buffer 開始的位置。默認值: 0。
end <integer> 新 Buffer 結束的位置(不包含)
buf.slice([start[, end]])
-->
</body>
js代碼
let buf = Buffer.from([97, 98, 99]);
console.log(buf); //<Buffer 61 62 63>
console.log(buf.toString());//abc
//以下寫入
let buf1 = Buffer.alloc(5); // <Buffer 00 00 00 00 00>
console.log(buf1);
buf1.write("abcdefg", 2, 2);
console.log(buf1); //<Buffer 00 00 61 62 00>
console.log(buf1.toString()); //ab
let buf2 = Buffer.from("abcdefg");
// let buf3 = buf2.slice();
let buf3 = buf2.slice(2); //<Buffer 63 64 65 66 67>
let buf4 = buf2.slice(2,4); //<Buffer 63 64>
console.log(buf3);
console.log(buf3.toString());//cdefg
3.Buffer靜態方法
<body>
<!--
1.檢查是否支持某種編碼格式
Buffer.isEncoding(encoding)
2.檢查是否是Buffer類型對象
Buffer.isBuffer(obj)
3.獲取Buffer實際字節長度
Buffer.byteLength(string[, encoding])
注意點: 一個漢字占用三個字節
4.合并Buffer中的數據
Buffer.concat(list[, totalLength])
-->
</body>
js代碼
// let res = Buffer.isEncoding("gbk");
// console.log(res);
// let obj = {};
// let obj = Buffer.alloc(5);
// let res = Buffer.isBuffer(obj);
// console.log(res);
// let buf = Buffer.from("123");
// let buf = Buffer.from("知播漁"); //9
let res = Buffer.byteLength(buf); //3
console.log(res);//漢字一個頂三個
console.log(buf.length);
let buf1 = Buffer.from("123");
let buf2 = Buffer.from("abc");
let buf3 = Buffer.from("xxx");
let res = Buffer.concat([buf1, buf2, buf3]);
console.log(res);//<Buffer 31 32 33 61 62 63 78 78 78>
console.log(res.toString());//123abcxxx
4.路徑模塊Path
<body>
<!--
1.路徑模塊(path)
封裝了各種路徑相關的操作
和Buffer一樣,NodeJS中的路徑也是一個特殊的模塊
不同的是Buffer模塊已經添加到Global上了, 所以不需要手動導入
而Path模塊沒有添加到Global上, 所以使用時需要手動導入
2.獲取路徑的最后一部分
path.basename(path[, ext])
let res = path.basename('/a/b/c/d/index.html'); index.html
let res = path.basename('/a/b/c/d'); d
let res = path.basename('/a/b/c/d/index.html', ".html"); index(除去.html)
3.獲取路徑
path.dirname(path)
let res = path.dirname('/a/b/c/d/index.html');/a/b/c/d
let res = path.dirname('/a/b/c/d');/a/b/c
4.獲取擴展名稱
path.extname(path)
let res = path.extname('/a/b/c/d/index.html'); .html
let res = path.extname('/a/b/c/d'); 空
console.log(res);
5.判斷是否是絕對路徑
path.isAbsolute(path)
注意點:
區分操作系統
在Linux操作系統中/開頭就是絕對路徑
在Windows操作系統中盤符開頭就是絕對路徑
在Linux操作系統中路徑的分隔符是左斜杠 /
在Windows操作系統中路徑的分隔符是右斜杠 \
let res = path.isAbsolute('/a/b/c/d/index.html'); // true
let res = path.isAbsolute('./a/b/c/d/index.html'); // false
let res = path.isAbsolute('c:\\a\\b\\c\\d\\index.html'); // true
let res = path.isAbsolute('a\\b\\c\\d\\index.html'); // false
6.獲取當前路徑環境變量分隔符
path.delimiter (windows是\ Linux是/)
path.delimiter用于獲取當前操作系統環境變量的分隔符的
如果是在Linux操作系統中運行那么獲取到的是 :
如果是在Windows操作系統中運行那么獲取到的是 ;
console.log(path.delimiter);
7.獲取當前操作系統路徑分隔符
path.sep (windows中使用; linux中使用:)
path.sep用于獲取當前操作系統中路徑的分隔符的
如果是在Linux操作系統中運行那么獲取到的是 左斜杠 /
如果是在Windows操作系統中運行那么獲取到的是 右斜杠 \
console.log(path.sep);
1.路徑的格式化處理
// path.parse() string->obj
let obj = path.parse("/a/b/c/d/index.html");
console.log(obj);
會轉化成以下格式
{
root: '/',
dir: '/a/b/c/d',
base: 'index.html',
ext: '.html',
name: 'index'
};
以下同理
// path.format() obj->string
2.拼接路徑
path.join([...paths])
注意點:
如果參數中沒有添加/, 那么該方法會自動添加
如果參數中有.., 那么會自動根據前面的參數生成的路徑, 去到上一級路徑
let str = path.join("/a/b", "c"); // /a/b/c
let str = path.join("/a/b", "/c"); // /a/b/c
let str = path.join("/a/b", "/c", "../"); // /a/b/c -- /a/b
let str = path.join("/a/b", "/c", "../../"); // /a/b/c -- /a
3.規范化路徑
path.normalize(path)
let res = path.normalize("/a//b///c////d/////index.html");
console.log(res);
\a\b\c\d\index.html
4.計算相對路徑
path.relative(from, to)
let res = path.relative('/data/orandea/test/aaa', '/data/orandea/impl/bbb');
console.log(res);
計算完之后是 ..\..\impl\bbb
5.解析路徑
path.resolve([...paths])
//如果后面是一個絕對路徑,就會忽略前邊的
let res = path.resolve('/foo/bar', 'baz'); // /foo/bar/baz
let res = path.resolve('/foo/bar', '../baz'); // /foo/baz
let res = path.resolve('/foo/bar', '/baz'); // /baz
-->
</body>
5.文件操作--fs模塊
5.1查看文件狀態
<body>
<!--
1.文件模塊(fs)
封裝了各種文件相關的操作
2.查看文件狀態
文件后面有sync的都是同步方法,沒有回調函數
fs.stat(path[, options], callback)
fs.statSync(path[, options])
-->
</body>
js代碼
fs.stat(__dirname, function (err, stats) {
// console.log("3");
// console.log(err);
// birthtime: 文件的創建時間
// mtime: 文件中內容發生變化, 文件的修改時間
// console.log(stats);
if(stats.isFile()){
console.log("當前路徑對應的是一個文件");
}else if(stats.isDirectory()){
console.log("當前路徑對應的是一個文件夾");
}
});
let stats = fs.statSync(__filename);
console.log(stats);
//補充 __dirname 為當前文件的上一級目錄
//__filename 為當前文件的目錄
5.2 文件讀取
<!--
1.文件讀取
fs.readFile(path[, options], callback)
fs.readFileSync(path[, options])
注意點:
沒有指定第二個參數, 默認會將讀取到的數據放到Buffer中
第二個參數指定為utf8, 返回的數據就是字符串
-->
js代碼
let fs = require("fs");
let path = require("path");
// 1.拿到需要讀取的文件路徑
let str = path.join(__dirname, "data.txt");
console.log(str);
// 2.讀取文件
/*
有回調函數的
fs.readFile(str,"utf8", function (err, data) {
if(err){
throw new Error("讀取文件失敗");
}
console.log(data);
// console.log(data.toString());
});
*/
let data = fs.readFileSync(str); //<Buffer 77 77 77 2e 69 74 36 36 36 2e 63 6f 6d>
let data = fs.readFileSync(str, "utf8"); //www.it666.com
console.log(data);
5.3 寫入文件
<body>
<!--
1.文件寫入
fs.writeFile(file, data[, options], callback)
fs.writeFileSync(file, data[, options])
寫入的內容既可以是字符串,也可以是buffer
-->
</body>
js代碼
let fs = require("fs");
let path = require("path");
// 1.拼接寫入的路徑
let str = path.join(__dirname, "lnj.txt");
// 2.寫入數據
let buf = Buffer.from("www.itzb.com");
fs.writeFile(str, buf, "utf-8", function (err) {
if(err){
throw new Error("寫入數據失敗");
}else{
console.log("寫入數據成功");
}
});
// let res = fs.writeFileSync(str, "知播漁 www.it666.com", "utf-8");
// console.log(res);
5.4 追加寫入
<!--
1.追加寫入
fs.appendFile(path, data[, options], callback)
fs.appendFileSync(path, data[, options])
-->
let fs = require("fs");
let path = require("path");
// 1.拼接寫入的路徑
let str = path.join(__dirname, "lnj.txt");
// 2.開始追加數據
fs.appendFile(str, "知播漁", "utf8", function (err) {
if(err){
throw new Error("追加數據失敗");
}else{
console.log("追加數據成功");
}
});
5.5 大文件操作
<body>
<!--
1.大文件操作
前面講解的關于文件寫入和讀取操作都是一次性將數據讀入內存或者一次性寫入到文件中
但是如果數據比較大, 直接將所有數據都讀到內存中會導致計算機內存爆炸,卡頓,死機等
所以對于比較大的文件我們需要分批讀取和寫入
fs.createReadStream(path[, options])
fs.createWriteStream(path[, options])
-->
</body>
js代碼:首先我們來看一下分批讀取
let fs = require("fs");
let path = require("path");
// 1.拼接讀取的路徑
let str = path.join(__dirname, "lnj.txt");
// 2.創建一個讀取流
//highWaterMark用來指定每次讀取的大小,單位是字節
let readStream = fs.createReadStream(str, {encoding : "utf8", highWaterMark : 1});
// 3.添加事件監聽 讀取時有以下幾種狀態
readStream.on("open", function () {
console.log("表示數據流和文件建立關系成功");
});
readStream.on("error", function () {
console.log("表示數據流和文件建立關系失敗");
});
readStream.on("data", function (data) {
console.log("表示通過讀取流從文件中讀取到了數據", data);
});
readStream.on("close", function () {
console.log("表示數據流斷開了和文件的關系, 并且數據已經讀取完畢了");
});
在看一下分批寫入
// 1.拼接寫入的路徑
let str = path.join(__dirname, "it666.txt");
// 2.創建一個寫入流
let writeStream = fs.createWriteStream(str, {encoding : "utf8"});
// 3.監聽寫入流的事件
writeStream.on("open", function () {
console.log("表示數據流和文件建立關系成功");
});
writeStream.on("error", function () {
console.log("表示數據流和文件建立關系失敗");
});
writeStream.on("close", function () {
console.log("表示數據流斷開了和文件的關系");
});
let data = "www.it666.com";
let index = 0;
let timerId = setInterval(function () {
let ch = data[index];
index++;
writeStream.write(ch);
console.log("本次寫入了", ch);
if(index === data.length){
clearInterval(timerId);
writeStream.end();
}
}, 1000);
文件拷貝
// 1.生成讀取和寫入的路徑
let readPath = path.join(__dirname, "test.mp4");
let writePath = path.join(__dirname, "abc.mp4");
// 2.創建一個讀取流
let readStream = fs.createReadStream(readPath);
// 3.創建一個寫入流
let writeStream = fs.createWriteStream(writePath);
// 利用讀取流的管道方法來快速的實現文件拷貝
readStream.pipe(writeStream);
5.6 目錄操作
<!--
1、創建目錄
fs.mkdir(path[, mode], callback)
fs.mkdirSync(path[, mode])
2、讀取目錄
fs.readdir(path[, options], callback)
fs.readdirSync(path[, options])
3、刪除目錄
fs.rmdir(path, callback)
fs.rmdirSync(path)
-->
js代碼
let fs = require("fs");
let path = require("path");
let str = path.join(__dirname, "abc");
//先創建abc目錄
fs.mkdir(str, function (err) {
if(err){
throw new Error("創建目錄失敗");
}else{
console.log("創建目錄成功");
}
});
//在刪除abc目錄
fs.rmdir(str, function (err) {
if(err){
throw new Error("刪除目錄失敗");
}else{
console.log("刪除目錄成功");
}
});
//寫一個遍歷當前文件所在目錄所有文件和文件夾
fs.readdir(__dirname, function (err, files) {
if(err){
throw new Error("讀取目錄失敗");
}else{
// console.log(files);
files.forEach(function (obj) {
// console.log(obj);
let filePath = path.join(__dirname, obj);
// console.log(filePath);
let stats = fs.statSync(filePath);
if(stats.isFile()){
console.log("是一個文件", obj);
}else if(stats.isDirectory()){
console.log("是一個目錄", obj);
}
});
}
})
利用目錄操作來快速創建一個項目模板如下
<body>
<!--
利用NodeJS生成項目模板
projectName
|---images
|---css
|---js
|---index.html
-->
</body>
js代碼
let fs = require("fs");
let path = require("path");
class CreateProject {
constructor(rootPath, projectName){
this.rootPath = rootPath;
this.projectName = projectName;
this.subFiles = ["images", "css", "js", "index.html"];
}
initProject(){
// 1.創建站點文件夾
let projectPath = path.join(this.rootPath, this.projectName);
fs.mkdirSync(projectPath);
// 2.創建子文件和子目錄
this.subFiles.forEach(function (fileName) {
if(path.extname(fileName) === ""){
let dirPath = path.join(projectPath, fileName);
fs.mkdirSync(dirPath);
}else{
let filePath = path.join(projectPath, fileName);
fs.writeFileSync(filePath, "");
}
})
}
}
let cp = new CreateProject(__dirname, "taobao");
cp.initProject();
6.HTTP模塊
6.1 服務器
<body>
<!--
1.什么是HTTP模塊
通過Nodejs提供的http模塊,我們可以快速的構建一個web服務器,
也就是快速實現過去PHP服務器的功能(接收瀏覽器請求、響應瀏覽器請求等)
2.通過HTTP模塊實現服務器功能步驟
2.1導入HTTP模塊
2.2創建服務器實例對象
2.3綁定請求事件
2.4監聽指定端口請求
-->
</body>
js代碼
// 1.創建一個服務器實例對象
let server = http.createServer();
// 2.注冊請求監聽
server.on("request", function (req, res) {
// end方法的作用: 結束本次請求并且返回數據
// res.end("www.it666.com");
// writeHead方法的作用: 告訴瀏覽器返回的數據是什么類型的, 返回的數據需要用什么字符集來解析
res.writeHead(200, {
"Content-Type": "text/plain; charset=utf-8"
});
res.end("知播漁");
});
// 3.指定監聽的端口
server.listen(3000);
//以下為簡寫
http.createServer(function (req, res) {
res.writeHead(200, {
"Content-Type": "text/plain; charset=utf-8"
});
res.end("知播漁666");
}).listen(3000);
6.2 路徑分發
<body>
<!--
1.什么是路徑分發?
路徑分發也稱之為路由, 就是根據不同的請求路徑返回不同的數據
2.如何根據不同的請求路徑返回不同的數據?
通過請求監聽方法中的request對象, 我們可以獲取到當前請求的路徑
通過判斷請求路徑的地址就可以實現不同的請求路徑返回不同的數據
-->
</body>
js代碼
let http = require("http");
// 1.創建一個服務器實例對象
let server = http.createServer();
// 2.注冊請求監聽
/*
request對象其實是http.IncomingMessage 類的實例,那么就可以使用該類中的方法
其中有個url方法能獲取到發出請求的網頁路徑比如127.0.0.1:3000/index 就會獲取到index
response對象其實是http.ServerResponse 類的實例
*/
server.on("request", function (req, res) {
res.writeHead(200, {
"Content-Type": "text/plain; charset=utf-8"
});
// console.log(req.url);
if(req.url.startsWith("/index")){
// 注意點: 如果通過end方法來返回數據, 那么只會返回一次,如果是下面的話,只會返回一句首頁1
// res.end("首頁1");
// res.end("首頁2");
// 注意點: 如果通過write方法來返回數據, 那么可以返回多次
// write方法不具備結束本次請求的功能, 所以還需要手動的調用end方法來結束本次請求
res.write("首頁1");
res.write("首頁2");
res.end();
}else if(req.url.startsWith("/login")){
res.end("登錄");
}else{
res.end("沒有數據");
}
});
// 3.指定監聽的端口
server.listen(3000);
6.3 響應靜態資源(網頁,圖片,視頻等)
<body>
<!--
1.響應靜態資源
需要注意的是:在給瀏覽器返回數據的時候,
如果沒有指定響應頭的信息,如果沒有設置返回數據的類型,
那么瀏覽器不一定能正確的解析
所以無論返回什么類型的靜態資源都需要添加對應的響應頭信息
-->
</body>
我們來實現一下
let http = require("http");
let path = require("path");
let ss = require("./15-StaticServer.js");
// 1.創建一個服務器實例對象
let server = http.createServer();
// 2.注冊請求監聽
server.on("request", function (req, res) {
let rootPath = path.join(__dirname, "www");//此時我們返回的是www目錄下的資源,這個根據需求來寫
//let rootPath = "C:\\Users\\Jonathan_Lee\\Desktop\\abc";
ss.StaticServer(req, res, rootPath);//在另一個文件封裝了一個方法,實現在下面
});
// 3.指定監聽的端口
server.listen(3000);
下為15-StaticServer.js文件
let path = require("path");
let fs = require("fs");
let mime = require("./mime.json");
function readFile(req, res, rootPath) {
let filePath = path.join(rootPath, req.url);
/*
注意點:
1.加載其它的資源不能寫utf8
2.如果服務器在響應數據的時候沒有指定響應頭, 那么在有的瀏覽器上, 響應的數據有可能無法顯示
* */
let extName = path.extname(filePath);
let type = mime[extName];//這是通過引入的json文件來判斷不同的后綴來指定什么形式
//以下即為該json文件的一些內容
//".323": "text/h323",
//".3gp": "video/3gpp",
if(type.startsWith("text")){
type += "; charset=utf-8;";
}
res.writeHead(200, {
"Content-Type": type
});
fs.readFile(filePath, function (err, content) {
if(err){
res.end("Server Error");
}
res.end(content);
});
}
exports.StaticServer = readFile;
6.4 獲取Get,post參數(為返回動態網站做準備)
6.4.1 首先來看獲取get參數
<body>
<!--
1.如何拿到Get請求傳遞過來的參數
使用URL模塊
url.format(urlObject) 將路徑轉換為對象
url.parse(urlString[, parseQueryString[, slashesDenoteHost]]) 將對象轉換為路徑
-->
</body>
js代碼
let url = require("url");
let http = require("http");
/*
let str = "http://root:123456@www.it666.com:80/index.html?name=lnj&age=68#banner";
let obj = url.parse(str, true);
obj里面包括各種信息,query里邊是get請求的參數本來字符串,
加上true就會將字符串轉化為對象,方便使用
console.log(obj);
console.log(obj.query.name); 這樣就能拿到get請求的參數
console.log(obj.query.age);
*/
// 1.創建一個服務器實例對象
let server = http.createServer();
server.on("request", function (req, res) {
// console.log(req.url);
let obj = url.parse(req.url, true);
res.end(obj.query.name + "----" + obj.query.age);
});
// 3.指定監聽的端口
server.listen(3000);
6.4.2 獲取post參數
<body>
<!--如下我們使用post提交一個表單,提交到//127.0.0.1:81/index.html-->
<form action="http://127.0.0.1:81/index.html" method="post">
<input type="text" name="userName">
<input type="text" name="password">
<input type="submit" value="提交">
</form>
<!--
1.如何拿到POST請求傳遞過來的參數
使用querystring模塊
querystring.parse(str[, sep[, eq[, options]]]) 將參數轉換為對象
querystring.stringify(obj[, sep[, eq[, options]]]) 將對象轉換為參數
-->
</body>
let http = require("http");
let queryString = require("querystring");
// 1.創建一個服務器實例對象
let server = http.createServer();
server.on("request", function (req, res) {
// 1.定義變量保存傳遞過來的參數
let params = "";
// 注意點: 在NODEJS中 ,POST請求的參數我們不能一次性拿到, 必須分批獲取
req.on("data", function (chunk) {
// 每次只能拿到一部分數據
params += chunk;
});
req.on("end", function () {
// 這里才能拿到完整的數據
// console.log(params);
let obj = queryString.parse(params);
// console.log(obj.userName);
// console.log(obj.password);
res.end(obj.userName + "----" + obj.password);
});
});
// 3.指定監聽的端口
server.listen(81);
6.4.3 區分GET-POST請求
<body>
<form action="http://127.0.0.1:3000/index.html" method="get">
<input type="text" name="userName">
<input type="text" name="password">
<input type="submit" value="提交">
</form>
<!--
1.在服務端如何區分用戶發送的是GET請求和POST請求?
通過HTTP模塊http.IncomingMessage 類的.method屬性
-->
js代碼
let http = require("http");
// 1.創建一個服務器實例對象
let server = http.createServer();
server.on("request", function (req, res) {
// console.log(req.method);
res.writeHead(200, {
"Content-Type": "text/plain; charset=utf-8"
});
if(req.method.toLowerCase() === "get"){
res.end("利用GET請求的方式處理參數");
}else if(req.method.toLowerCase() === "post"){
res.end("利用POST請求的方式處理參數");
}
});
// 3.指定監聽的端口
server.listen(3000);
6.5 返回動態網站
index.html
<body>
<form action="./info.html" method="post">
<input type="text" name="userName">
<input type="submit" value="查詢">
</form>
</body>
info.html
<body>
<ul>
<!--<li>姓名: !!!name!!!</li>
<li>性別: !!!gender!!!</li>
<li>年齡: !!!age!!!</li>-->
<li>姓名: <%=name%></li>
<li>性別: <%=gender%></li>
<li>年齡: <%=age%></li>
</ul>
</body>
js模塊
let http = require("http");
let path = require("path");
let fs = require("fs");
let url = require("url");
let queryString = require("querystring");
let template = require("art-template");
let persons = {
"lisi": {
name: "lisi",
gender: "male",
age: "33"
},
"zhangsan": {
name: "zhangsan",
gender: "female",
age: "18"
}
};
// 1.創建一個服務器實例對象
let server = http.createServer();
// 2.注冊請求監聽
server.on("request", function (req, res) {
if(req.url.startsWith("/index") && req.method.toLowerCase() === "get"){
let obj = url.parse(req.url);
let filePath = path.join(__dirname, obj.pathname);
fs.readFile(filePath, "utf8", function (err, content) {
if(err){
res.writeHead(404, {
"Content-Type": "text/plain; charset=utf-8"
});
res.end("Page Not Found");
}
res.writeHead(200, {
"Content-Type": "text/html; charset=utf-8"
});
res.end(content);
});
}
else if(req.url.startsWith("/info") && req.method.toLowerCase() === "post"){
let params = "";
req.on("data", function (chunk) {
params += chunk;
});
req.on("end", function () {
let obj = queryString.parse(params);
let per = persons[obj.userName];
// console.log(per);
let filePath = path.join(__dirname, req.url);
/*
fs.readFile(filePath, "utf8", function (err, content) {
if(err){
res.writeHead(404, {
"Content-Type": "text/plain; charset=utf-8"
});
res.end("Page Not Found");
}
content = content.replace("!!!name!!!", per.name);
content = content.replace("!!!gender!!!", per.gender);
content = content.replace("!!!age!!!", per.age);
res.end(content);
});
*/
// 下為通過模板來修改內容
let html = template(filePath, per);
res.writeHead(200, {
"Content-Type": "text/html; charset=utf-8"
});
res.end(html);
});
}
});
// 3.指定監聽的端口
server.listen(3000);