前端Node的實用方法
Node
一、什麼是Node
Node是以基於Chrome V8引擎的JavaScript運行環境,使用了一個事件驅動、非阻塞式I/O模型(I/O是 input/output的縮寫,即輸入輸出埠,在傳統的編程模式中,I/O操作阻塞了程式碼的執行,極大的降低了程式的效率),Node的出現讓JavaScript 運行在服務端的開發平台,具有相當重要的意義
二、初識Node
1、路徑
node通過ch
切換路徑到文件路徑,node的工作路徑如果不切換會導致操作的失敗d:
可以切換盤符,通過ch
切換到工作文件
2、命令獲取路徑
在Node中,可以通過node命令來獲取相對路徑
*__dirname: 可以獲取到當前js文件所屬的目錄的絕對路徑.*
*__filename: 可以獲取當前js文件的絕對路徑.*
3、引入內置path模組
const fs = require('fs');
const path = require('path');
const fullPath = path.join(__dirname, '/data');
console.log(fullPath);
fs.writeFile(fullPath, '么么噠!', 'utf-8', err=>{
if(err) return console.log(err);
console.log('yes yyds!!!');
});
4、Buffer
因為JavaScript語言自身只有字元串數據類型,沒有二進位數據類型,但在處理TCP流或文件流時必須使用二進位數據,所以Node.js定義了一個專門存放二進位數據的快取區Buffer,在讀取文件時,返回data數據時Buffer類型,所以需要轉換為字元串
fs.readFile('./data/1.txt',(err, data) => {
if(err){
return console.log('讀取發生錯誤:'+err);
}
console.log( data.toString());
});
三、http模組
http的簡單圖解
const http = require('http');
//創建1個服務
const server = http.createServer((request, response) => {
response.end('Hello, Node.js!');
});
//監聽服務
server.listen(3000, () => console.log('服務啟動成功'));
1、示例-獲取URL讀取文件的內容
const http = require('http');
const fs = require('fs');
const path = require('path');
const server = http.createServer((req, res) => {
//1.將url 和 method 轉換為小寫
req.url = req.url.toLowerCase();
req.method = req.method.toLowerCase();
const fullPath = path.join(__dirname, 'www', req.url);
fs.readFile(fullPath, (err, data) => {
if(err){
//讀取文件發生錯誤了. 路徑錯了.
res.statusCode = 404;
res.end();
}else{
res.end(data);
}
});
});
server.listen(80, ()=>console.log('服務正在監聽'));
2、createServer的回調
1.執行時機:只要有來自客戶端的HTTP請求,這個函數就會被執行
2.回調函數的兩個參數
req對象,客戶端向服務端發的數據都被封裝在req對象中
req.url 可以獲取請求時候的url及其參數
req.method 可以獲取客戶端請求服務端的方法,post/delete/put/patch/head等
res對象,客戶端響應給服務端的數據全部被封裝在其中,
res.setHeader(),響應數據新增響應頭,通過Content-Type可以返回指定數據的類型
3、請求分為兩部分
請求頭,鍵值對,作用是告訴瀏覽器一些關鍵的資訊
請求體,發給伺服器的數據
4、響應分為兩部分
響應頭 鍵值對 作用: 瀏覽器會根據響應頭中的數據可能會做出一些處理.
響應體 伺服器真正返回給瀏覽器的數據. 瀏覽器會解析響應體中的數據.
響應數據
res.write() 向響應體中寫入數據
res.end(); 結束響應寫入的數據.
5、常見狀態碼
常見狀態碼:
200: 伺服器處理請求成功
201: 處理成功 並且創建了新的資源
400: 瀏覽器發送給伺服器的數據有問題, 一般都是參數傳遞錯誤.
127.0.0.1/api/joke?num=10
401: 身份驗證過期.或者沒有驗證.
403: 許可權不足.
404: 資源不存在.
500: 伺服器內部發生錯誤.
四、npm使用
1、初始化
npm init -y //保存了初始化項目的資訊
package.json
其中dependencies: 記錄了我們下載的插件和版本.
其中scripts屬性.
我們可以將一些常用的命令保存在 package.json中的scripts屬性中,
npm run xxx; 就可以執行對應的命令.(webstorm不需要,🤭)
2、下載包
npm install 包名@版本號
3、刪除包
npm uninstall 包名
五、express模組
1 express對象.
這個對象中就有一些方法.
static
2 Application對象.
其實就是我們創建的應用.
3 Request對象
回調函數中的 第1個參數 req
4 Response對象
回調函數中的 第2個參數 res
5 Router對象
路由對象.
const express = require('express');//引入
//創建express應用(服務)
const app = express();
app.get(path,(req,res)=>{res.send()})
app.post(path,(req,res)=>{res.send()})
app.use()//
app.use('/api/student', stuRouter);//註冊路由
app.use(express.urlencoded({extended: false}));//註冊中間件
app.use(express.static('public'));//靜態頁面託管
req.query
req.body//設置中間件之後再使用
1、express模組的文件讀取和寫入(轉換)
//讀取本地文件生成五條隨機數據
app.get('/api/v2/joke', (req, res) => {
//從jokes.json文件中隨機的取1條笑話.
fs.readFile(path.join(__dirname, 'data/jokes.json'), 'utf-8', (err, data) => {
if (err) {
//發生錯誤. 500
return res.status(500).send({
code: 500,
msg: '伺服器內部發生錯誤'
});
}
//讀取的時候,沒有發生錯誤.
// 將讀取出來的數據轉換為一個數組. 讀取出來的數據是1個字元串.
const jokes = JSON.parse(data); // 8880
//隨機5個.
// 產生5個隨機的下標.
const retunJokes = [];
const set = new Set();
while(set.size != 5){
//產生的下標不能重複.
const index = Math.floor(Math.random() * jokes.length);
set.add(index);
}
//執行到這裡,就代表set中存儲了5個不重複的下標.
// set 14 98 5412 27 49
for(let index of set){
retunJokes.push(jokes[index]);
}
res.send({
code: 200,
count: jokes.length,
joke: retunJokes
});
});
});
app.listen(80, () => console.log('服務啟動成功'));
2、express託管靜態頁面
//引入第三方模組
const express = require('express');
//調用服務
const app = express();
app.use(express.static(path.join(__dirname, 'public')));
//127.0.0.1/static/index.html
//app.use('/static', express.static('public'));
app.listen(80, ()=>console.log('服務啟動成功'));
六、module
module.export和exports都是Node中的頂層對象,但是為了避免混淆,用module.exports完全足夠,它默認是返回一個空對象,並且讓其他的文件在引入的時候也可以進行使用,讓各個文件之間有了聯繫
七、CommonJS規範
CommonJS規範是JavaScript的一種模組化規範,它規定了JavaScript如何進行分模組。而Node.js的模組化是遵循CommonJS規範.
模組化:
如果將所有的程式碼都寫在1個文件中
- 難以維護
- 不利於團隊開發.
將項目分為一個一個的模組,按照功能
不要把所有的程式碼寫在同1個文件中,而是將程式碼按照功能分開 分開在一個一個的單獨的模組中
分為三個模組
1、內置模組
2、文件模組
readFile: 非同步讀取文件
writeFile: 非同步寫入文件.
使用require
函數一樣可以載入文件模組。
3、第三方模組:本質是文件模組
八、router模組
1.創建router對象
const express = require('express');
const stuHandler = require('../handler/stuHandler.js');
const router = express.Router();
2.在router對象上註冊路由
router.get('/delete', stuHandler.delete);//第一個參數是對應的url部分路徑,第二個參數是邏輯處理模組對應的程式碼
router.post('/update', stuHandler.update);//第一個參數是對應的url部分路徑,第二個參數是邏輯處理模組對應的程式碼
3.將router對象暴露出去 module.exports
九、邏輯處理模組
這塊程式碼才是文件的核心部分,書寫了具體的請求處理邏輯
以學生管理系統的刪除功能的程式碼為例
module.exports.delete = (req, res) => {
//1. 獲取瀏覽器傳遞給伺服器的id
const { id } = req.query;
//2. 判斷有沒有這個id 400
if (!id) return res.status(400).send({ code: 400, msg: '參數錯誤' });
//3. 有這個id 就去學生庫中刪除這個id的學員.
//3.1 先從學生庫中讀取出所有的學員
const stus = require(jsonPath);
//3.2 循環數組,判斷數組中是否有一個學員的id剛好等於傳過來的id
let findIndex = -1;
for (let i = 0; i < stus.length; i++) {
if (stus[i].id == id) {
//將當前遍歷出來的這個學員從數組中刪除.
findIndex = i;
break;
}
}
//這個是在文件內的JSON數據讀取和查找,效率相對比較低,在學習MySQL後可以進一步精簡
//循環結束以後,如果findIndex的值是-1 說明id不存在.
if (findIndex == -1) return res.status(404).send({ code: 404, msg: 'id不存在' });
// 說明id存在.
// 先從數組中將這個元素刪除.
stus.splice(findIndex, 1);
// 這個刪除只是刪除了記憶體中的數組中的元素. json文件中的數據是不會變的.
// 將stus數組的數據重新寫入到json文件中.
fs.writeFile(path.join(__dirname, jsonPath), JSON.stringify(stus), 'utf-8', err => {
if (err) return res.status(500).send({ code: 500, msg: err });
res.send({ code: 200, msg: '刪除成功' });
});
}