Express基礎
文章目錄
一.前言
基於Node.js平臺,快速,開放,極簡的Web開發框架
1.框架的作用
框架可以幫助省略掉一些基本的相同底層代碼的反覆書寫,只需調用框架的方法就可以實現你想要的功能。
回顧
nodejs入門之web服務搭建 https://blog.csdn.net/liuqiao0327/article/details/105058145
nodejs入門之get和post請求 https://blog.csdn.net/liuqiao0327/article/details/105086003
這兩篇文章。寫原生實現總是非常繁瑣且費時的。
2.Node相關的框架
-
express
-
koa
-
egg
-
thinkjs
-
adonisjs
-
nestjs
…
二.Express簡介
Express 是一個簡潔而靈活的 node.js Web應用框架, 提供了一系列強大特性幫助你創建各種 Web 應用,和豐富的 HTTP 工具。
使用 Express 可以快速地搭建一個完整功能的網站。
Express 框架核心特性:
-
可以設置中間件來響應 HTTP 請求。
-
定義了路由表用於執行不同的 HTTP 請求動作。
-
可以通過向模板傳遞參數來動態渲染 HTML 頁面。
三.安裝Express
安裝 Express 並將其保存到依賴列表中:
$ npm install express
四,使用,搭建一個express的服務
//快速搭建一個基於express框架的web服務
//1. 引入express
const express = require('express');
//2. 生成一個express實例,
const app = express();
//3. 處理各種請求
//處理請求路徑localhost:3000/index
app.get('/index', (req, res) => {
res.send("express 基礎");//這裏相當於不用框架時的 res.write+ res.end
});
//處理請求路徑localhost:3000/details
app.get('/details',(req,res)=>{
res.send("詳情頁")
});
//4. 監聽3000端口
app.listen(3000, () => {
console.log("服務啓動成功");
});
五.路由
路由是指確定應用程序如何響應客戶端(瀏覽器)對特定端點的請求,該特定端點是URL(或路徑)和特定的HTTP請求方式(GET、POST等)。
每個路由可以具有一個或多個處理程序函數,這些函數在路由匹配時執行。
1.路由的基本語法
app.METHOD(PATH,[...HANDLER]) app.get('/index',()=>{})
- 1.app是express的實例
- 2.METHOD 是小寫的 HTTP 請求方式(GET、POST、PUT、PATCH、DELETE等)。
- 3.PATH 是請求路徑 (以/開頭)
- 4.HANDLER 是當路由匹配時執行的函數。
下面是一些路由,可以使用postman去訪問,會有相應的回覆
//引入express模塊
const express = require('express');
//創建一個express的實例
const app = express();
/**
* 下面是一些路由
*/
app.get('/', (req, res) => {
res.send("Get / 響應");
});
app.post('/', (req, res) => {
res.send("Post / 響應")
});
app.get('/index', (req, res) => {
res.send("Get index響應");
});
app.get("/details", (req, res) => {
res.send("Get details響應");
});
app.delete('/delete', (req, res) => {
res.send("delete 響應");
});
//監聽端口
app.listen(3000, () => {
console.log("服務啓動成功");
});
2.請求參數的獲取
1.query參數(?號傳參)
const express = require('express');
const app = express();
//http://localhost:3000
//這裏通過get請求 http://localhost:3000?username=zhangsan&age=18
app.get('/', (req, res) => {
//http://localhost:3000
console.log(req.query);//返回一個對象 {}
//http://localhost:3000?username=zhangsan&age=18
console.log(req.query);//返回一個對象 { username: 'zhangsan', age: '18' }
res.send(req.query);
});
app.listen(3000,()=>{
console.log("服務啓動成功");
});
- Route Path : /
- Request URL : http://localhost:3000?username=zhangsan&age=18
- req.query : { name: ‘zhangsan’, age: ‘18’ }
2.body參數 (請求體傳參)
注意,req.body需要設置中間件
const express = require('express');
const app = express();
/**
* 使用req.body的時候,需要調用express.json ()和express.urlencoded()
* app.use(express.json);
* app.use(express.urlencoded)
*/
//處理json格式 的請求體
app.use(express.json());
//處理 x-www-form-xvasdfasdfasdf 這種格式
app.use(express.urlencoded({
extended:true
}));
app.post('/getBody', (req, res) => {
//console.log(req.body);//undefined 因爲沒有設置中間件
console.log(req.body.username);//設置中間之後可以獲取
console.log(req.body.age);//設置中間之後可以獲取
res.send(req.body);//設置中間之後返回的是對象{ username: 'zhangsan', age: '18' }
});
app.listen(3000, () => {
console.log("服務啓動成功");
});
注意
/**
* 處理 請求體參數的 解析。
* Express 4.16.0 起 提供了內置的 express.json() 和 express.urlencoded()
* 當然他們內部還是基於 bodyParser 的
*/
// app.use(express.json())
// app.use(express.urlencoded({ extended: true }))
這是最新的處理方式
在expresss 4.16.0之前,還是使用的 bodyParser 第三方模塊
npm install body-parser
/**
* 處理 請求體參數的 解析
* Express 4.16.0 之前使用 bodyParser 第三方模塊
*/
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }))
- Route Path : /getBody
- Request URL : http://localhost:3000/getBody
- Request BODY: username=lisi&password=123456或者 { username: ‘lisi’, password: ‘123456’ }
- req.body : { username: ‘lisi’, password: ‘123456’ }
3. params 參數(動態路徑傳參)也就是動態路由
//http://localhost:3000/user/app app
//http://localhost:3000/user/web web
//http://localhost:3000/user/moblie moblie
// 冒號後面的可以當做變量 動態路由
app.get('/users/:userRoute', (req, res) => {
// 我們要想讓這三個路徑都能進來就要做下區分
//req.params=>{userRoute:'app'}
console.log(req.params);
res.send(req.params);
});
//http://localhost:3000/user/x/app/y
//http://localhost:3000/user/1234/app/34444
//這種長路徑,含有變量的
app.get('/user/:userId/app/:bookId', (req, res) => {
console.log(req.params);
res.send(req.params); //{ userId: '1234', bookId: '34444' }
});
- Route Path : /users/:userId/books/:bookId
- Request URL : http://localhost:3000/users/34/books/8989
- req.params : { userId: ‘34’, bookId: ‘8989’ }
3.路由處理函數
路由處理函數是一種類似於 中間件函數 的方法。一個路由可以同時設置多個路由處理函數。
路由語法接收三個參數:
- req:request 請求對象
- res:response 響應對象
- next:調用它執行下一個匹配的路由處理函數
// 路由處理函數
/**
* 回顧路由語法
*
* app.METHOD(path, [...HANDLER])
*
* HANDLER 接收的參數
* 1. req 請求對象
* 2. res 響應對象
* 3. next 是個函數,調用它執行下一個匹配的路由處理函數
*
* HANDLER 是可以有多個的
*/
app.get('/', (req, res, next) => {
console.log(1);
next();//必須要寫,纔可以進入下一個處理函數
}, (req, res, next) => {
console.log(2);
next();
}, (req, res) => {
console.log(3);
res.send("執行完畢"); // 1 2 3
});
app.listen(3000,()=>{
console.log("服務啓動成功");
});
上面是多個回調以參數列表的形式組合
// 多個回調,以數組形式
app.get('/index', [(req, res, next) => {
console.log(1);
next();//必須要寫,纔可以進入下一個處理函數
}, (req, res, next) => {
console.log(2);
next();
}, (req, res) => {
console.log(3);
res.send("執行完畢");
}]);
上面是多個回調,以數組形式
// 數組與普通的結合
app.get('/hello', [
(req, res, next) => {
console.log(1)
next()
},
(req, res, next) => {
console.log(2)
next()
}
], (req, res, next) => {
console.log(3)
res.send('hello world')
})
還可以數組與普通的結合
4.express.Router
使用 express.Router 類來創建模塊化的,可安裝的路由處理程序。一個 Router 實例是一個完整的中間件和路由系統。
思考如下代碼:
當項目做大做強時,index.js 文件將異常龐大。不利於後續的項目維護。
比如以下代碼:
// index.js
const express = require('express')
const app = express()
app.get('/', (req, res) => { res.send('GET / 響應') })
app.get('/posts', (req, res) => { res.send('GET /posts 響應') })
app.post('/posts', (req, res) => { res.send('POST /posts 響應') })
app.get('/posts/create', (req, res) => { res.send('GET /posts/create 響應') })
app.get('/posts/:id', (req, res) => { res.send('GET /posts/xxid 響應') })
app.put('/posts/:id', (req, res) => { res.send('PUT /posts/xxid 響應') })
app.get('/posts/:id/edit', (req, res) => { res.send('GET /posts/xxid/edit 響應') })
app.delete('/posts/:id', (req, res) => { res.send('DELETE /posts/xxid 響應') })
app.get('/books', (req, res) => { res.send('GET /books 響應') })
app.post('/books', (req, res) => { res.send('POST /books 響應') })
app.get('/books/create', (req, res) => { res.send('GET /books/create 響應') })
app.get('/books/:id', (req, res) => { res.send('GET /books/xxid 響應') })
app.put('/books/:id', (req, res) => { res.send('PUT /books/xxid 響應') })
app.get('/books/:id/edit', (req, res) => { res.send('GET /books/xxid/edit 響應') })
app.delete('/books/:id', (req, res) => { res.send('DELETE /books/xxid 響應') })
app.listen(3000)
這時就可以將相同類別的路由處理代碼抽離到單獨的文件中,最後在主程序(這裏指 index.js)中加載。比如:
1.抽離 posts 相關的存放到 routes/posts.js 文件中
// routes/posts.js
const express = require('express')
const router = express.Router()
router.get('/', (req, res) => { res.send('GET /posts 響應') })
router.post('/', (req, res) => { res.send('POST /posts 響應') })
router.get('/create', (req, res) => { res.send('GET /posts/create 響應') })
router.get('/:id', (req, res) => { res.send('GET /posts/xxid 響應') })
router.put('/:id', (req, res) => { res.send('PUT /posts/xxid 響應') })
router.get('/:id/edit', (req, res) => { res.send('GET /posts/xxid/edit 響應') })
router.delete('/:id', (req, res) => { res.send('DELETE /posts/xxid 響應') })
// 不要忘了暴露出去
module.exports = router
2.抽離 books 相關的存放到 routes/books.js 文件中
// routes/books.js
const express = require('express')
const router = express.Router()
router.get('/', (req, res) => { res.send('GET /books 響應') })
router.post('/', (req, res) => { res.send('POST /books 響應') })
router.get('/create', (req, res) => { res.send('GET /books/create 響應') })
router.get('/:id', (req, res) => { res.send('GET /books/xxid 響應') })
router.put('/:id', (req, res) => { res.send('PUT /books/xxid 響應') })
router.get('/:id/edit', (req, res) => { res.send('GET /books/xxid/edit 響應') })
router.delete('/:id', (req, res) => { res.send('DELETE /books/xxid 響應') })
// 不要忘了暴露出去
module.exports = router
3.在主程序中(index.js)中引入並使用
// index.js
const express = require('express')
// 引入
const postsRouter = require('./routes/posts.js')
const booksRouter = require('./routes/books.js')
const app = express()
app.get('/', (req, res) => { res.send('GET / 響應') })
// 使用
app.use('/posts', postsRouter)
app.use('/books', booksRouter)
app.listen(3000)