nodejs入門之Express基礎

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.路由處理函數

路由處理函數是一種類似於 中間件函數 的方法。一個路由可以同時設置多個路由處理函數。

路由語法接收三個參數:

  1. req:request 請求對象
  2. res:response 響應對象
  3. 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)

參考鏈接

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章