初入nodejs

shaodao發表於2024-08-29

序言:

為了真正實現自己上線一個軟體 從現在開始學習後端

初入nodejs學到的內容:

首先理解的後端流程大概輪廓是

  1. 建立伺服器
  2. 編寫路由
  3. 編寫路由攔截器(GET、POST)
  4. 連線資料庫
  5. 實現資料庫的增刪改查

接著就是學習express.js 和 Koa.js 這兩個基於nodejs的框架

我們一步一步來

建立伺服器

http.createServer傳入一個方法來建立伺服器
該方法入參 request 和 response 即為訪問伺服器的請求和響應

程式碼中的writeHead用於寫響應的頭部 透過改變Content-Type來改變響應體的資料型別

對資料的響應 程式碼中也有體現出來
一種是響應非檔案資料 則使用 res.end()的語法 ,將內容以字串形式放入進行響應
另外一個響應檔案資料,程式碼中響應一個html檔案,則使用fs來建立一個讀取流,使用管道pipe將流傳入response中

var http = require("http");
var fs = require("fs")
const { stringify } = require("querystring");

var service = http.createServer(function(req , res){
    console.log("request");
    
    // 傳輸資料
    res.writeHead(200 , {
        // "Content-Type" : 'text/plain' // 傳輸文字
        "Content-Type" : 'text/html' // 傳輸html
        // "Content-Type" : 'application/json' // 傳輸json
    })// 設定請求頭

    var obj = {
        name : "name",
        id : "id"
    }
    // res.end(JSON.stringify(obj))

    // 可以利用讀取檔案進行傳輸
    var myReadStream = fs.createReadStream(__dirname + '/index.html' , 'utf8');
    myReadStream.pipe(res)
})  

// 監聽伺服器
service.listen(3000,'127.0.0.1') // 埠以及本地地址

編寫路由

我對路由的理解 其實就是使用介面進行請求時 介面的key值
例如 localhost:8000/api/getData 這裡的/getData就是路由的主體
透過編寫路由來確認 前端請求哪些什麼介面獲取什麼資料
我認為也就是後端與前端的主要連線位置

在這裡直接使用一個較為複雜的例子來講解

首先啟動伺服器,這裡將啟動服務的程式碼封裝起來 server.js

var http = require('http');

/**
 * 啟動伺服器
 * @param {*} router 路由表與伺服器的連線函式
 * @param {*} handle 路由表 
 */
function startServer(router, handle){
    var server = http.createServer(function(request , response){
        router(handle,request.url,response)
    })

    server.listen(3000,'127.0.0.1')
    console.log("伺服器執行在3000埠上")

}

module.exports = {
    startServer
}

在index.js檔案中匯入
封裝的startServer傳入兩個引數 分別為路由處理方法router以及路由表handle

var server = require('./server.js')
var handler = require('./handle.js')
var router = require('./router.js')

/**
 * 相當於路由表 路由對應的埠
 */
var handle = {}
handle['/'] = handler.home
handle['/home'] = handler.home
handle['/user'] = handler.user

server.startServer(router, handle)

可以理解為 handle 來指明你請求的哪個路由對應了哪個路由的響應方法
router 即為他們的操盤手 將 response 和 path 和 handle 結合在一起

因此有handle.js:

var fs = require('fs')
var data = require('./user.js')

// 給予埠 封裝埠狀態碼以及傳遞的內容(html\json)
function home(response){
    response.writeHead(200 , {"Content-Type" : 'text/html'})
    fs.createReadStream(__dirname + '/home.html','utf8').pipe(response)
}

function user(response){
    response.writeHead(200 , {"Content-Type" : 'application/json'})
    response.end(JSON.stringify(data))
}

module.exports = {
    home,
    user
}

router.js:

var fs = require('fs')

/**
 * 
 * @param {*} handle 路由表
 * @param {*} pathname url
 * @param {*} response 傳入介面介面 將要渲染的內容放入此處
 */
function router(handle,pathname,response){
    if(typeof handle[pathname] === 'function'){
        handle[pathname](response)
    }else{
        response.writeHead(404 , {"Content-Type" : "text/html"});
		fs.createReadStream(__dirname + "/404.html","utf8").pipe(response);
    }
}

module.exports =  router

可能有點繞 當時學的時候也花蠻長時間才順通

路由攔截實現GET、post請求

上一節學習的路由編寫裡的請求 其實都是get請求 預設如此
而工作中最常見的還是POST請求

首先要認清GET和POST的區別
對於我來說 最大的區別就是POST傳引數是在負載中 GET傳引數是在路由末尾透過?的形式新增

因此 我們首先需要獲取請求中的引數
GET請求獲取的思路是擷取後面一段url POST是使用庫方法直接獲取
可以透過request.method來區分POST還是GET

因此server.js:

var http = require('http');
var url = require('url')
var querystring = require('querystring')


/**
 * 啟動伺服器
 * @param {*} router 路由表與伺服器的連線函式
 * @param {*} handle 路由表 
 */
function startServer(router, handle){
    var server = http.createServer(function(request , response){
        console.log(request.url) // 獲取整段url
        var pathname = url.parse(request.url).pathname
        console.log(pathname) // 獲取url中的pathname部分
        var data = [] // 用於儲存從介面中獲取的資料
        var params = {} // 用於儲存請求中的資料
        request.on('error' , function(err){
            console.log(err); // 輸出報錯
        }).on('data' , function(chunk){
            data.push(chunk) // 儲存資料
        }).on('end',function(){ // 讀取結束
            console.log(request.method) // 輸出請求型別
            if(request.method === 'POST'){
                data = Buffer.concat(data).toString(); // 此時被轉化為字串型別
                data = querystring.parse(data)
                params = data
            }else if(request.method === 'GET'){
                var param = url.parse(request.url,true).query // 獲取url中的引數部分  url?name="xxx" true:【物件】 false:【字串】
                params = param
            }else{}
        })


        // router(handle,request.url,response)
        // 為避免伺服器連同引數部分一起讀取從而無法判斷正確url , 應該用pathname部分代替整段url
        router(handle,pathname,response,params)
    })

    server.listen(3000,'127.0.0.1')
    console.log("伺服器執行在3000埠上")

}

module.exports = {
    startServer
}

獲取到引數後用params進行裝載 透過router傳入handle handle再根據params進行特殊處理即可

連線資料庫

連線資料庫很簡單 有個包叫mysql
第一步 安裝mysql包
npm install mysql --save--dev
第二步 使用程式碼進行資料庫連線:

const mysql = require('mysql2/promise');  
  
async function connectToDatabase() {  
    try {  
        const connection = await mysql.createConnection({  
            host: 'localhost',  
            user: 'yourUsername',  
            database: 'yourDatabaseName',  
            password: 'yourPassword',  
            waitForConnections: true,  
            connectionLimit: 10,  
            queueLimit: 0  
        });  
  
        await connection.connect();  
  
        console.log('成功連線到MySQL資料庫');  
  
        // // 示例:插入資料(INSERT)  
        // const insertQuery = 'INSERT INTO yourTable (column1, column2) VALUES (?, ?)';  
        // const insertResult = await connection.execute(insertQuery, ['value1', 'value2']);  
        // console.log('插入資料成功', insertResult);  
  
        // // 示例:查詢資料(SELECT)  
        // const selectQuery = 'SELECT * FROM yourTable WHERE column1 = ?';  
        // const [rows, fields] = await connection.execute(selectQuery, ['value1']);  
        // console.log('查詢結果', rows);  
  
        // // 示例:更新資料(UPDATE)  
        // const updateQuery = 'UPDATE yourTable SET column2 = ? WHERE column1 = ?';  
        // const updateResult = await connection.execute(updateQuery, ['newValue', 'value1']);  
        // console.log('更新資料成功', updateResult.affectedRows);  
  
        // // 示例:刪除資料(DELETE)  
        // const deleteQuery = 'DELETE FROM yourTable WHERE column1 = ?';  
        // const deleteResult = await connection.execute(deleteQuery, ['value1']);  
        // console.log('刪除資料成功', deleteResult.affectedRows);  
  
        // 關閉連線  
        await connection.end();  
  
    } catch (error) {  
        console.error('連線到MySQL資料庫時發生錯誤:', error);  
    }  
}  
  
connectToDatabase();

程式碼裡還寫了關於資料庫的增刪改查的簡單方法
ps:此段程式碼還未執行過 本人另外在express.js框架裡也用過該包成功進行資料庫連線

nodejs基於webSocket實現聊天功能

主要是之前看別人用go寫websocket覺得好高大上 當時自己搞半天都沒搞通 現在知道js也可以寫後端就趕緊來試著實現

安裝 ws

首先,你需要透過 npm 安裝 ws 庫。在你的 Node.js 專案目錄下開啟終端或命令提示符,然後執行:

npm install ws

建立 WebSocket 伺服器

以下是一個簡單的 WebSocket 伺服器示例,使用 ws 庫:

const WebSocket = require('ws');

const wss = new WebSocket.Server({ port: 8080 });

wss.on('connection', function connection(ws) {
  ws.on('message', function incoming(message) {
    console.log('received: %s', message);
  });

  ws.send('something');
});

console.log('WebSocket server is running on ws://localhost:8080');

在這個例子中,伺服器監聽 8080 埠,並在每個新的 WebSocket 連線上列印接收到的訊息,並向客戶端傳送一條訊息。

建立 WebSocket 客戶端

客戶端可以使用原生的 WebSocket API,如果你是在瀏覽器環境中,或者你也可以在 Node.js 中使用 ws 庫來模擬客戶端:

const WebSocket = require('ws');

const ws = new WebSocket('ws://localhost:8080');

ws.on('open', function open() {
  ws.send('Hello Server!');
});

ws.on('message', function incoming(data) {
  console.log(data);
});

ws.on('error', function error(err) {
  console.error(err);
});

這段程式碼建立了一個 WebSocket 客戶端,連線到 ws://localhost:8080,傳送一條訊息,並列印從伺服器接收到的任何訊息。

相關文章