web 開發之node.js
前言:從零開始講node.js長篇預警(建議收藏),這看這篇部落格之前你需要了解下mysql資料庫和javascript 這兩樣我的部落格都有介紹。接下來就請各位指教了,感謝!
1.Node.js概述
簡單的說 Node.js 就是執行在服務端(即後端)的 JavaScript。
(1)對比JS和Node.js
JS是執行在客戶端瀏覽器,存在多款瀏覽器,存在程式碼相容性問題;
Node.js是執行在伺服器端,只有一種環境,不存在相容性問題。
兩者都有內建物件、自定義物件,不同的宿主物件
JS用於開發瀏覽器端的互動效果,Node.js用於伺服器端的開發,資料庫的操作、其它伺服器的訪問..
(2)node.js特點及應用場景
單執行緒執行邏輯,適合做基於社交網路的大規模的web應用,例如微博、抖音...
2.node.js 的物件(部分)
(1)global
檢測一個變數或者函式是不是全域性下的,如果是可以通過global來訪問 (注意:
Node.js下每一個檔案都是在一個模組作用域下,變數和函式都是區域性的,有效的防止汙染全域性。
) js相對node.js的global 的全域性物件是 window
(2)console
console.log(1); //日誌
console.info(2); //訊息
console.warn(3) ; //警告
console.error(4); //錯誤
console.time('canshu1') //開始計時
console.timeEnd('canshu1') //結束計時
開始計時和結束計時兩者的引數要保持一致。
(3)process物件 程序
process.arch 檢視CPU的架構
process.platform 檢視當前的作業系統版本
process.version 檢視當前Node.js的版本
process.pid 檢視當前程序的編號
process.kill() 結束指定編號的程序
(4)Buffer物件 緩衝區、緩衝器,位於記憶體中,臨時儲存資料的區域,常用於儲存網路傳輸的資源,例如線上視訊..
Buffer.alloc(5, 'abcde') 建立buffer為5個位元組,並存儲資料,1個漢字佔3個位元組。可以用
String() / toString() 將buffer轉為字串
3.模組
模組是一個獨立的功能體,每一個檔案都是模組他們之間是引入和被引入的關係
模組分為自定義模組、核心模組、第三方模組
require: 是一個函式,用於引入其它的模組 如引入檔案系統模組:
var fs = require('fs')
module.exports: 當前模組匯出的內容,預設是一個空物件,如果要匯出哪些內容,只需要放入到物件中。(可以用於匯出自定義的模組)
模組下的兩個區域性變數
__dirname: 當前模組的絕對目錄
__filename: 當前模組的絕對目錄和模組名稱
console.log(__filename);
console.log(__dirname);
模組的分類:
(1)檔案形式的引入:
require('./ziDingYi.js') 用於當前目錄下引入自定義模組 (目錄可以自己更改,這裡為了便於理解就引用的當前目錄)
require('querystring') 用於引入官方提供的核心模組
(2) 目錄形式的引入:
require('./ziDingYi') 首先會到目錄下package.json檔案中尋找main屬性對應的檔案,如果找不到則會自動尋找index.js檔案對其引用。
require('fs') 會到當前目錄下的node_modules目錄中尋找fs目錄,如果找不到會一直往上一級的node_modules目錄中尋找 用於引入第三方模組
4.包和 npm
包(package):就是第三方的模組,是目錄形式的模組如(mysql等)
npm:管理包的工具,包括下載安裝、上傳、解除安裝、升級... nodejs安裝的時候自動附帶安裝
可以在命令視窗 鍵入npm -v 檢視npm的版本號
常用的npm 命令有
npm init -y 初始化專案說明檔案package.json
npm config get registry獲取當前下載倉庫的地址
npm config set registry https://registry.npm.taobao.org設定下載倉庫地址為淘寶映象(改為國內下載)
npm install 包的名稱下載安裝指定的包,會自動將包放入node_modules目錄中,如果node_modules目錄不存在會自動建立;會在package.json中記錄下載安裝的包名稱和版本號;會生成檔案package-lock.json,用於記錄依賴的包的版本號。
npm install自動安裝package.json和package-lock.json中記錄的已經安裝的包的名稱和版本號。
npm run 快捷名稱自動到package.json中,scripts下對應的名稱並執行(前提是要先自行設定並儲存好)如圖
npx 在npm5.2以後自動安裝的工具(所以安裝較高版本的node.js 比較好)
npx -p node@8 node 檔名稱在使用nodejs執行檔案之前,先去下載指定的nodejs版本,然後再執行檔案;執行完以後再把下載的nodejs刪除。(這樣有效的避免了重複下載不同版本的node.js,在一個版本可執行其他版本的node.js大大提高了工作效率)
5.查詢字串模組(querystring)
查詢字串是瀏覽器端向web伺服器傳遞資料的一種方式,位於URL中如
parse() 將查詢字串解析為物件,可以得到傳遞的資料
const querystring = require('querystring'); var str = querystring.parse('https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=%E5%8D%9A%E5%AE%A2&fenlei=256&rsv_pq=a167532500056e60&rsv_t=4268GA7vo5%2BGdEItQc5kgZOrMGHT%2FsfWlhWJcswkRReOt7LvQ9VfmQFEKkU&rqlang=cn&rsv_dl=tb&rsv_enter=1&rsv_sug3=6&rsv_sug2=0&rsv_btype=i&inputT=1291&rsv_sug4=1955'); console.log(str);
得到一個物件可以通過屬性呼叫
6.URL模組
URL: 統一資源定位,網際網路上任何資源都有對應的URL,通過這個URL可以找到該資源。
http://www.baidu.com:9999/product_details.html?lid=5
協議域名/IP地址埠檔案的路徑查詢字串
parse() 將URL解析為物件,可以獲取各個部分
7.定時器模組
(1)一次性定時器
開啟 var timer=setTimeout(回撥函式, 間隔時間); //當間隔時間到了,呼叫一次回撥函式,單位是毫秒。 清除 clearTimeout(timer);
(2)週期性定時器
開啟 var timer=setInterval(回撥函式, 間隔時間); //每隔一段時間,呼叫一次回撥函式 清除 clearInterval(timer)
(3)立即執行的定時器
開啟 var timer=setImmediate( 回撥函式 ) 清除 clearImmediate(timer)
process.nextTick( 回撥函式 ) 無法清除
兩者都是立即執行的定時器,都是在事件佇列的最前邊,process.nextTick比setImmediate更先執行
所有定時器都會在事件佇列裡排隊,其他程式碼優先執行
8.檔案系統模組fs
伺服器端的檔案分為檔案形式和目錄形式
//引入fs模組 const fs=require('fs'); //1-------------------------------------------------檢視檔案狀態 //同步:通過返回值獲取結果 var s=fs.statSync('../day02'); //console.log( s.isFile() );//是否為檔案形式 console.log( s.isDirectory() );//是否為目錄形式 console.log(s); //非同步:通過回撥函式來獲取結果 fs.stat('./01.js',(err,s)=>{ //err 可能產生的錯誤結果 //s 成功獲取到的結果 if(err){ throw err; } console.log(s); }); //2------------------------------------.-----------------讀取目錄 //同步 //var arr=fs.readdirSync('../day02'); //console.log(arr); //非同步 readdir fs.readdir('../day02',(err,arr)=>{ if(err){ throw err; } console.log(arr); }); //3.--------------------------------------------------------建立目錄 //fs.mkdirSync('./mydir'); //非同步建立mydir2 mkdir fs.mkdir('./mydir2',(err)=>{ if(err) throw err; console.log('目錄建立成功'); }); //4---------------------------------------------------------.移除目錄 //fs.rmdirSync('./mydir'); fs.rmdir('../day02',(err)=>{ if(err) throw err; }); //5.---------------------------------------------------------寫入檔案 //fs.writeFileSync('./1.txt','ran'); fs.writeFile('./2.txt','tedu',(err)=>{ if(err) throw err; }); // 如果檔案不存在,先建立檔案然後寫入資料 如果檔案已經存在,會覆蓋寫入資料 //6.---------------------------------------------------------追加寫入 fs.appendFile('./3.html','WEB前端2011\n',(err)=>{ if(err) throw err; console.log('檔案寫入成功'); }); //如果檔案不存在,先建立檔案然後寫入資料 如果檔案已經存在,會在檔案的末尾追加寫入資料 //7.----------------------------------------------------------讀取檔案 var data=fs.readFileSync('./stu.txt'); //buffer data得到的是buffer形式的物件 console.log(data); //轉字串 console.log( String(data) ); //使用非同步方法讀取3.html fs.readFile('./3.html',(err,data)=>{ if(err) throw err; console.log( String(data) ); }); //8.------------------------------------------------------------刪除檔案 //同步 //fs.unlinkSync('./1.txt'); //非同步 //fs.unlink('./.txt',(err)={ if(err) throw err; }); //9.----------------------------------------------------------檢測檔案是否存在 var res=fs.existsSync('../day02'); //非同步形式已經棄用 console.log(res); 反回 true 或者 false //拷貝檔案 fs.copyFileSync('./3.html','./mydir/3.txt'); //copyFileSync(原始檔路徑, 目標檔案路徑) / copyFile(原始檔路徑, 目標檔案路徑, 回撥函式)
9.同步和非同步
同步:會阻止後續程式碼的執行,先執行完當前的再往後執行,通過返回值來獲取結果。
非同步:不會阻止後續程式碼的執行,在一個獨立的執行緒執行,通過回撥函式來獲取結果
10.檔案流
//引入fs模組 const fs = require('fs'); //建立可讀取的檔案流 var rf = fs.createReadStream('./1.zip'); //建立可寫入的檔案流 var wf = fs.createWriteStream('./mydir/2.zip'); //寫入的檔名可以改但型別最好不要改 //把讀取的流通過管道新增到寫入流 rf.pipe(wf);
可以通過事件監聽,是否有資料流入
//data 資料流入事件,固定的 //一旦事件被觸發,通過回撥函式來獲取資料 var count=0;//用於記錄讀取的段數 rs.on('data',(chunk)=>{ //on(事件名稱, 回撥函式) 用來新增事件 //chunk 獲取到的分段資料 //console.log(chunk); //得到的chunk物件千萬不要轉字串否則容易宕機 //每讀取一段加1 count++; }); //console.log(count); //監聽讀取結束事件 rs.on('end',()=>{ console.log(count); //檢視總共有多少條資料流 });
10.http協議是客戶端和web伺服器之間的通訊協議 (這裡只做簡單的介紹)
(1)通用的頭資訊 (這些資訊可以通過瀏覽器檢查 檢視到)
Request URL: 請求的URL,請求的資源
Request Method: 請求的方法, get/post/delete/put...
Status Code: 響應的狀態碼
1**:伺服器端接收到了請求,還沒做出響應
2**:成功的響應
3**:響應的重定向,會跳轉到另一個URL
4**:客戶端請求錯誤
5**:伺服器端錯誤
(2)響應的頭資訊response
Content-Type:響應的內容型別, html對應text/html 還有編碼設定
Location:設定跳轉的URL
(3)請求的頭資訊request
(4)請求的主體
可有可無,用於設定傳遞資料
11.node.js中的http模組用於建立web伺服器
const http=require('http'); //建立web伺服器 const app=http.createServer(); //設定埠 app.listen(8080); //新增事件,監聽是否有請求 app.on('request',(req,res)=>{ //req 請求的物件 console.log(req.url,req.method); //req下兩個常用的方法可以獲取url和請求方式 //res 為響應的物件 /* //設定響應的狀態碼和頭資訊 res.writeHead(200,{ //若狀態碼為404 可以不用新增頭資訊(回掉函式) //設定內容型別和編碼 'Content-Type': 'text/html;charset=utf-8' }); //設定響應的內容 res.write('<h1>這是內容</h1>'); //結束併發送響應 res.end(); //設定響應的狀態和跳轉的URL res.writeHead(302,{ Location: 'http://www.tmooc.cn' }); //結束併發送響應 res.end(); */
通過不同的url反回不同的網頁如下:
const http=require('http'); const fs=require('fs'); const app=http.createServer(); app.listen(8080); //新增事件 app.on('request',(req,res)=>{ //根據請求做出響應 if(req.url==='/login'){ res.writeHead(200,{ 'Content-Type':'text/html;charset=utf-8' }); res.write('<h1>這是登入的網頁</h1>'); }else if(req.url==='/study'){ res.writeHead(302,{ Location: 'http://www.tmooc.cn' }); }else if(req.url==='/index'){ //讀取1.html檔案 var data=fs.readFileSync('./1.html'); //把讀取到的資料響應 res.write(data); }else{ res.writeHead(404); res.write('not found'); } //結束併發送響應 res.end(); });
可見引用http模組建立web伺服器端比較麻煩於是便有了比較方便的express第三方模組
npm install express //下載express框架
12.express框架 express是一款基於Node.js平臺,快速、開放、極簡的WEB開發框架
框架是一整套的解決方案,已有的功能進行封裝簡化,添加了一些沒有功能。
//引入express包 const express=require('express'); //console.log(express); //可以看到express本身是一個function 且含有很多function //建立web伺服器 const app=express(); //設定埠 app.listen(8080); //可見比http模組簡單
要想設定看到客戶端和服務端的請求和響應還需要另一個概念:路由
(2)路由 :伺服器端根據請求的方法和請求的URL來做出特定的響應,例如註冊有註冊的路由,登入有登入的路由... 路由,由請求的方法、請求的URL、回撥函式組成。
//引入express包 const express=require('express'); //console.log(express); //可以看到express本身是一個function 且含有很多function //建立web伺服器 const app=express(); //設定埠 app.listen(8080); //登入的路由 //請求的方法:get 請求的URL:/login app.get('/login',(req,res)=>{ res.send('<h1>這是登入的網頁</h1>'); // res.send 設定響應內容併發送 並結束響應
}); //添加註冊的路由 //請求的方法:get 請求的URL: /reg //響應'<h2>請註冊</h2>' app.get('/reg',(req,res)=>{ res.send(` <h2>請註冊</h2> 請輸入使用者名稱 `); }); //路由 //請求的方法:get 請求的URL:/study app.get('/study',(req,res)=>{ //響應的重定向 res.redirect('http://www.cnblogs.cn'); }); //新增首頁的路由 //請求的方法:get 請求的URL:/ //跳轉到登入的路由 /login app.get('/',(req,res)=>{ res.redirect('/login'); //res.redirect() 設定響應的重定向,跳轉到另一個URL
}); //路由 //請求的方法:get 請求的URL:/index app.get('/index',(req,res)=>{ //響應檔案併發送 res.sendFile(__dirname+'/1.html'); //設定響應的檔案併發送,使用檔案的絕對路徑
res.sendFile()
});
上面多介紹了響應的方法 下面為請求的方法
//引入查詢字串模組
const querystring=require('querystring');
const app=express();
app.listen(8080);
//響應搜尋頁面get /search app.get('/search',(req,res)=>{ res.sendFile(__dirname+'/search.html'); }); //根據表單的請求建立對應的路由(get /mysearch),響應'搜尋成功' app.get('/mysearch',(req,res)=>{ //console.log(req.url,req.method); //req.url req.method獲取的請求的URL,請求的方法 console.log(req.query); //req.query獲取請求的查詢字串形式的資料 res.send('搜尋成功'); }); //路由 get /login app.get('/login',(req,res)=>{ res.sendFile(__dirname+'/login.html'); }); //根據表單請求建立路由 post /mylogin app.post('/mylogin',(req,res)=>{ //獲取post傳遞資料,以流的方式 //通過事件的方式,一旦資料流入,自動獲取 req.on('data',(chunk)=>{ //console.log( chunk ); var data=String(chunk); console.log(data);//查詢字串 //引入查詢字串模組,解析為物件 var obj=querystring.parse(data); console.log(obj); }); res.send('登入成功'); }); //新增路由(get /package),響應'這是包的使用詳情' app.get('/package/:pname',(req,res)=>{ // "/:pname" url的形式引數 實參在瀏覽器中傳入可以是多個
console.log(req.params); //req.params獲取路由傳參形式的資料
res.send('這是包的使用詳情'); });
總結:路由中獲取資料的方式:
以URl傳遞的一個URL的字串 通過req.query獲取資料 其 格式為物件
以流方式傳遞來的資料,通過事件方式獲取資料
req.on('data',(chunk)=>{ //得到的chunk格式為buffer,轉字串後為查詢字串,需要解析為物件 String(chunk) //再通過其屬性就可以獲得對應的屬性值了 })
通過路由傳參得到的資料需要對應形參來接收
app.get('/package/:pname',(req,res)=>{ // “/:pname” :形參 req.params // //獲取路由傳參形式的資料 格式為物件 });
雖然有了路由可見簡化很多程式碼 但是當遇到url重名時卻無可奈何 於是便有了路由器
(3)路由器 其作用是把同一模組下的所有路由放到一起,最終掛載到web伺服器,而且可以個同意個模組下所有的URL新增統一的字首 這也是一箇中間件(後面再詳細介紹)
建立路由程式碼如下
const express= require('express'); //引用express框架,因為路由器是express下的一個方法 const u= express.Router(); //建立路由器 u.get('/list',(req,res)=>{ //新增url以及反回的內容 res.send('這是使用者列表'); }); module.exports=u //匯出路由器
為了便於理解再建立一個路由器
const express=require('express'); //與上面的相比是兩個不同的js檔案 const p=express.Router(); p.get('/list',(req,res)=>{ res.send('這是商品列表') }); module.exports=p; //module.exports後面是等於一個物件的但是這裡只寫了一匯出物件 就直接省略了{}
路由器建立好了接下來是呼叫路由的中介軟體
const express=require('express'); //引入express框架啊模組 const shangpingRouter=require('./router/p.js'); //這裡寫的路徑是上面路由器檔案的路徑 const yonghuRouter = require('./router/u.js'); //匯入另一個路由器 const app = express(); //建立伺服器 app.listen(8080); //設定埠號 app.use('/v1/product',shangpingRouter); //將路由器掛載到伺服器上 app.use('/v1/user',yonghuRouter); //相當於是一個路由級的中介軟體,當
開啟伺服器後新增對應的字尾名後就可以訪問到對應的網頁了
上面提到了中介軟體接下來講講中介軟體是怎麼回事
13.中介軟體 可以按照URL攔截客戶端對伺服器端的請求,中介軟體可以分為應用級(自定義)中介軟體,路由級中介軟體,內建中介軟體,第三方中介軟體,錯誤處理中介軟體 這裡分別舉例其中的代表性操作 詳情可以檢視其官網
(1)應用級中介軟體 也稱自定義的中介軟體是一個函式
const express=require('express'); const app=express(); app.listen(8080); function fun(req,res,next){ if(req.query.name!=='root'){ res.send('無法訪問') //滿足條件做出響應 }else{ next() }; //不滿足條件執行路由 } app.use(‘/list’,fun) //攔截URL為list時啟用中介軟體 呼叫回掉函式注意有三個引數 app.get('/list',(req,res)=>{ res.send('歡迎登陸'); });
其中的回撥函式可以根據需求寫不同規則
(2)路由級中介軟體 也即是路由器的使用 app.use(URL,引入的路由器) 見上面 的路由器有詳細介紹
(3)內建中介軟體 這是express提供好的,可以直接拿來用 如靜態資源請求即是託管靜態資源,當瀏覽器端請求靜態資源,伺服器端不需要建立路由,而是由讓瀏覽器端自動的到指定的目錄下查詢。
const express=require('express'); const app= express(); app.listen(8081); app.use(express.static('./public')); //託管靜態資源到public目錄
在位址列輸入對應的靜態資原始檔名就會自動到public目錄下尋找並在網頁上呈現出來(前提一定要有對應的檔案)
public下有1.html檔案
(4)第三方中介軟體 屬於第三方模組的形式 需要下載安裝 這裡以body-parser中介軟體為例
npm install body-parser 下載安裝
body-parser中介軟體 用於將所有的post請求的資料(流)解析為物件 有點類似於querystring模組但比其簡單些
//下載好body-parser模組後 const express = require('express'); const bodyParser=require('body-parser'); //引入模組 const app=express(); app.listen(8082); //將所有的post請求資料解析為物件 app.use(express.static('./public')); //引入提前寫好的html檔案(html內設定資料請求方式為post) app.use(bodyParser.urlencoded({extended:false})) //方法括號裡的內容可以不寫但會報錯 ,不影響整體的程式碼 app.post('/myblog',(req,res)=>{ var data=req.body; //得到html的請求資料物件 res.send('響應成功'); //可以響應上面的資料內容 });
到此中介軟體的介紹 這裡只是極少舉例 各個中介軟體的常見基礎使用方式
14.mysql 模組 屬於第三方模組需要下載
npm install mysql
下載好後就可以引用mysql 進一步操作資料庫了
const mysql = require('mysql'); const c =mysql.createConnection(); //建立連線物件 //c.connect() //執行連線資料庫 用於測試 c.query('select * from 表 where id=2',(err,result)=>{}) //這句話會預設連線資料庫,執行sql語句,通過回撥函式可以返回結果
上面的SQL語句中可以在條件處引入客戶端的請求資訊程式碼如下
const express=require('express'); const mysql =require('mysql'); const app=express(); const c=mysql.createConnection({ host:'localhost', user:'root' , port:'3306', password:'', database:'yaoshiyongdeshujuku' }); app.get('/zidingyi/:id',(req,res)=>{ //字串傳參 var data = req.params.id; c.query(`select * from where id=${data}`,(err,result)=>{ //用模板字串將外面的變數引入 if(err) throw err; res.send(result); }); });
但是上面的程式碼容易產生SQL注入,若是在字串傳參的時候在最後加‘or 1=1 ’就會把所有的資料響應 為了避免上面的情況我們可以用陣列過濾字串
//在上面的程式碼中做如下修改 c.query(`select * from where id=?`,[id],(err,result)=>{
這樣一來可以有效的防止sql注入 因為陣列會過濾掉非表中的資料
接下來便是關於連線池的知識
上面連線資料庫的方式mysql.createConnection({})雖然實現了業務需求但是建立連線時,只有一個連線,它會一直持續到關閉它(或者它被mysql伺服器關閉).我們可以通過引用傳遞它並重新使用它,也可以按需建立和關閉連線.
而建立的連線池是儲存連線的地方.當您從池請求連線時,您將收到當前未使用的連線或新連線.如果您已經處於連線限制,它將等待連線可用,然後才能繼續.這些池化連線不需要手動關閉,它們可以保持開啟狀態並且易於重複使用.
我們使用的連線方式完全取決於我們的業務需求,建立連線池的方式和上面的也差不多
const mysql = require('mysql') const pool=mysql.createPool({ host:'localhost', user:'root', port:'3306', password:'', database:'shujukumingzi', connectionLimit:'15' //設定連線數量不宜過大 可以不用設定這行有預設值 }) pool.query('sql語句',()=>{}) //使用連線池操作資料庫
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
想必學到這裡我們已經感受到每次程式碼的改動都要執行命令視窗在到瀏覽器執行檢視,這這。。。樣搞開發已經不是頭禿而是鍵盤禿了,各位看官覺得呢?反正你們也不點贊,我就當你們鍵盤沒禿,下面的東東可以不用看了,哼!!
這時我們就要引入介面和一種比較流行的介面設計風格(規範)RESTful
先來聊聊介面 我們知道URL:對應請求的資源
介面就是
https ://i.cnblogs.com /posts/edit;postId=14169722
協議 域名/IP地址 埠路由 查 詢字串
RESTful介面規範其中路由的格式
/v1/zidingyi/1
/v1/zidingyi?s1=5000
/v1/users/3
/v1/users/checkuname
/版本號/資源/資源的編號
請求的方法 這裡知識一部分其實還有很多就不一一列舉了
插入資料post
刪除資料delete
修改資料 put
查詢資料 get
返回結果json物件
{"code":"狀態碼","msg":"訊息內容"}
{"code":200, "msg": data: [] }
上圖:
15.ApiPost 一款用於測試介面的工具 ,有了這個就不用為了個post請求建heml檔案傳資料再開執行等等一頓影響開發效率的事了。
這是下載地址給各位大佬奉上https://pan.baidu.com/s/14znej-KdtDQS-0xjpxluDw軟體登陸好後的使用方法如下:
軟體準備好了接下就開始介紹資料庫操作及伺服器程式碼結合該軟體的使用吧 ## 不過這一切的前提是下面所用到模組都要安裝好喲!
就以一個簡單的專案為例吧先看看專案的目錄結構
這是檔案的圖片
基本結構已經知道了接下來是程式碼了
首先是路由器user.js
const epxpress= require('express'); //優先匯入express模組 const u = express.Router(); //呼叫express模組下的router方法建立路由器 u.post('/reg',(req,res)=>{ //簡單建立個路由,並做出響應 res.send('ok') }); module.exports=u; //匯出 路由器
然後是伺服器app.js引入路由器操作
const express = require('express');
const bodyParser = require('body-parser'); //引入body-parser模組供後面使用
const app = express(); app.listen(8080); //建立伺服器和埠
app.use(bodyParser.urlencoded({extended:false})) //避免報錯 const rRouter = require('./router/user.js') //匯入路由器 app.use('/v1/users',rRouter); //用中介軟體新增字首並使用
再然後是在同級目錄下建立連線池pool.js
const mysql = require('mysqsl'); const pool = mysql.createPool({ host:-----, port:----, user:----, password:-----, database:------, //這些內容介紹mysql已經介紹過就不贅述了 connectionLimit:--- }); module.exports= pool; //匯出連線池
連線池建立好之後就是在user.js中匯入 加上下面的程式碼即可
const pool = require('../pool.js') //在上一級目錄中找到pool.js檔案
接下來就是介紹通過路由器對資料庫進行增刪改查的程式碼 一切以上面已有的程式碼為基準 畢竟重複的程式碼太過累贅
首先是對資料庫的增加內容在user.js下進行
u.post('/zeng',(req,res)=>{ var data = req.body; //由於app.js中已經匯入了body-parser模組 這裡可以直接使用body方法 ,匯入有Apipost軟體傳來的body物件 var num = 400; for(var i in data){ num++; if(data[i]){ //這裡可以做判斷傳來的值是否為空做出相應的響應,後面我就略過了 res.send(code:num,msg:i+'值不能為空'); return; } } pool.query('insert into biao set ?',[data],(err,result)=>{ if(err){ console.log(err); //打印出可能的錯誤 並做出響應 res.send(code:500,msg:'伺服器端錯誤!') //之後的介紹中這裡是重複我將略過 return; } res.send(code:200,msg:'新增資訊成功') //新增成功後做出的響應 }); });
在命令視窗執行app.js後對應aipPost 上的軟體操作如下:
接下來是刪 程式碼如下
u.delete(‘/delete/:uid’,(req,res)=>{ var data = req.params.uid; //判斷是否為空這裡的程式碼我就不贅述與上面類似 pool.query('delete from biao where id=?',[data],(err,result)=>{ //輸入刪除的sql語句 if(err) throw err //寫法與上面類似這裡不贅述 if(result.affectedRows){ //affectedRows為result物件的屬性,若找到對應的id並刪除成功後的值為1 res.send({code:200,msg:'刪除成功'}); }else{ res.send({code:201,msg:'刪除失敗,未找到該id'}) } }); });
對應apipost軟體操作如圖:
接下來是 更改 的程式碼:
u.put('/update/:uid',(req,res)=>{ var data =req.params.uid; var data2 = req.body; pool.query('update biao set ? where uid=? ',[data2,data],(err,result)=>{ if(err) thorw err; if(result.affectedRows){ res.send({code:200,msg:'修改成功',data:result}) }else{ res.send({code:201,msg:'修改失敗(可能是編號不存在)'}) } }); });
對應apipost軟體操作如圖:
接下來是 查普通查詢我就不介紹了說說分頁查詢吧!程式碼奉上:
u.get(‘/cha’,(req,res)=>{ var ye = req.query.pno; //得到通過字串傳參得到的引數 var shu = req.query.count; if(!ye||ye==0){ //如果為0或空設定預設值 ye=1; } if(!shu){ //設定預設值 shu =5; } var start = (ye-1)*shu; //已經隱式轉換為數值為limit做準備 shu = parseInt(shu); //強制轉為數值 pool/.qeury('select * from biao limit ?,?',[start,shu],(err,result)=>{ //注意limit後面空格必須 if(err) throw err if(!result[0]){ //得到的result為數值如有結果不為空 res.send({code:200,msg:'查詢成功',data:result}); }else{ res.send({code:201,msg:'未查詢到目標,請輸入正確的開始值'}); } }); });
最後是apiport軟體的操作:
到此就可以寫下簡單的專案了
到這node.js就介紹的差不多了 編寫不宜多多點贊轉發感謝給位! 有不足之處還望指教!