將路由設計與應用的進入點分開
通常應用程式會有一個進入點(ex. app.js),藉此驅動其他的程式碼,如果將路由邏輯寫在同個檔案會使單一檔案變得很攏長。幸好express.js提供很方便的方法讓我們簡單使用自己所創造的路由
假設我們將管理員使用的路由寫在admin.js,把給使用者利用的路由寫在shop.js檔案
admin.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| const express = require('express');
const router = express.Router();
router.use('/add-product', (req, res, next) => { res.send('<form action="/product" method="POST"><input type="text" name="title"><button type="submit">Add Product</button></form>'); }); router.post('/product', (req, res, next) => { console.log(req.body); res.redirect('/'); });
module.exports = router;
|
shop.js
1 2 3 4 5 6 7 8 9
| const express = require('express');
const router = express.Router();
router.get('/', (req, res, next) => { res.send('<h1>Hello from Express!</h1>'); });
module.exports = router;
|
接著就可以在app.js引入這些routes
app.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| const express = require('express'); const bodyParser = require('body-parser');
const adminRouter = require('./routes/admin'); const shopRouter = require('./routes/shop');
const app = express();
app.use(bodyParser.urlencoded({extended: false}));
app.use(shopRouter); app.use(adminRouter);
app.listen(3000);
|
當路由不符合任何一個設計的路徑時回傳一個404 page
1 2 3 4
| app.use((req, res, next) => { res.status(404).send("<h1>Page not found</h1>") })
|
共同路徑與相同路徑
可以使用相同的路徑來處理不同類型的請求
1 2 3 4 5 6 7 8
| router.get('/admin/add-product', (req, res, next) => { res.send('<form action="/product" method="POST"><input type="text" name="title"><button type="submit">Add Product</button></form>'); }); router.post('/admin/add-product', (req, res, next) => { console.log(req.body); res.redirect('/'); });
|
如果路徑中有重複的部分,可以做以下更動
app.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| const express = require('express'); const bodyParser = require('body-parser');
const adminRouter = require('./routes/admin'); const shopRouter = require('./routes/shop');
const app = express();
app.use(bodyParser.urlencoded({extended: false}));
app.use(shopRouter); app.use('/admin', adminRouter);
app.listen(3000);
|
如此一來admin.js改成以下
1 2 3 4 5 6 7 8 9 10
| router.get('/add-product', (req, res, next) => { res.send('<form action="/admin/add-product" method="POST"><input type="text" name="title"><button type="submit">Add Product</button></form>'); });
router.post('/add-product', (req, res, next) => { console.log(req.body); res.redirect('/'); });
|
回傳html檔案及正確的檔案路徑
回傳完整的html檔案可以使用res.sendFile(‘路徑’),但這個路徑必須以作業系統的根部路為基礎的絕對路徑,且路徑的顯示方式可能因作業系統不同而不同,所以我們要使用另一個nodeJS core module,path
假設我們專案內檔案結構如下圖
admin.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| const path = require('path');
const express = require('express');
const router = express.Router();
router.get('/add-product', (req, res, next) => { res.sendFile(path.join(__dirname, '../', 'views', 'add-product.html')) }); router.post('/product', (req, res, next) => { console.log(req.body); res.redirect('/'); });
module.exports = router;
|
如果不想每次都要根據不同的檔案路徑來輸入不同的路徑字串,可以統一使用進入點當作絕對路徑,再輸入相對路徑
首先創個資料夾,裡面新增一個path.js
檔案
path.js
1 2 3
| const path = require('path');
module.exports = path.dirname(process.mainModule.filename);
|
之後我們可以在每個需要routes路徑的檔案引入path.js
檔,再根據整個專案作為根目錄輸入正確的相對路徑
admin.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| const path = require('path');
const express = require('express'); const rootDir = require('../util/path');
const router = express.Router();
router.get('/add-product', (req, res, next) => { res.sendFile(path.join(rootDir, 'views', 'add-product.html')) }); router.post('/product', (req, res, next) => { console.log(req.body); res.redirect('/'); });
module.exports = router;
|
引入靜態資料
html檔案內直接撰寫CSS雖然可以運作,但是為了專案的整潔及方便管理,需要把CSS作為外部檔案再引入html內,直接使用路徑引入style
將無法運作,所以我們需要express幫我們定義靜態檔案的資料夾位置
在app.js加入這一行
app.js
1 2
| app.use(express.static(path.join(__dirname, 'public')));
|
接著在html檔案內就可以引入放在public
資料夾內的CSS檔案或圖片
<link rel= "stylesheet" href = "css/main.css">
往後引入靜態檔案時 (CSS, js, picture etc.),node就會先去尋找是否在我們設定的static路徑裡面,而這個路徑可以設定複數個。
參考資料