路由
基礎
目錄結構:
root
├── api.js
├── index.js
├── route.js
├── server.js
│
└── static
├── 404.html
├── favicon.ico
├── home.html
└── login.html
- route.js
js
const fs = require('fs');
function render(res, path, type = '') {
res.writeHead(200, { 'Content-Type': `${type ? type : 'text/html'};charset=utf8` });
res.write(fs.readFileSync(path), 'utf-8');
res.end();
}
const route = {
'/login': (req, res) => {
render(res, './static/login.html');
},
'/home': (req, res) => {
render(res, './static/home.html');
},
'/404': (req, res) => {
res.writeHead(404, { 'Content-Type': 'text/html;charset=utf8' });
res.write(fs.readFileSync('./static/404.html'), 'utf-8');
res.end();
},
'/favicon.ico': (req, res) => {
render(res, './static/favicon.ico', 'image/x-icon');
},
};
module.exports = route;
- api.js
js
function render(res, data, type = '') {
res.writeHead(200, { 'Content-Type': `${type ? type : 'application/json'};charset=utf8` });
res.write(data);
res.end();
}
const apiRouter = {
'/api/login': (req, res) => {
render(res, `{"ok":1}`);
},
};
module.exports = apiRouter;
- server.js
js
const http = require('http');
const Router = {};
function use(obj) {
Object.assign(Router, obj);
}
function start() {
const server = http.createServer((req, res) => {
const url = new URL(req.url, 'http://127.0.0.1');
try {
Router[url.pathname](req, res);
} catch {
Router['/404'](req, res);
}
});
server.listen(3000, () => console.log('localhost:3000'));
}
exports.start = start;
exports.use = use;
- index.js
js
const server = require('./server');
const route = require('./route');
const api = require('./api');
// 註冊路由
server.use(route);
server.use(api);
server.start();
獲取參數
GET
js
'/api/login': (req, res) => {
const url = new URL(req.url, 'http://127.0.0.1');
if (
url.searchParams.get('username') === 'sheep' &&
url.searchParams.get('password') === '123456'
) {
render(res, `{"ok":1}`);
} else {
render(res, `{"ok":0}`);
}
}
POST
js
'/api/loginpost': (req, res) => {
let post = '';
// 透過 req 的 data 事件監聽函式,每當接受到請求體的資料,就累加到 post 變數中
req.on('data', (chunk) => {
post += chunk;
});
req.on('end', () => {
console.log(post);
post = JSON.parse(post);
if (post.username === 'sheep' && post.password === '123456') {
render(res, `{"ok":1}`);
} else {
render(res, `{"ok":0}`);
}
});
}
靜態資源處理
js
const fs = require('fs');
const path = require('path');
// npm i mime
const mime = require('mime');
const route = {
'/login': (req, res) => {
render(res, './static/login.html');
},
'/': (req, res) => {
render(res, './static/home.html');
},
'/home': (req, res) => {
render(res, './static/home.html');
},
'/404': (req, res) => {
if (readStaticFile(req, res)) return;
res.writeHead(404, { 'Content-Type': 'text/html;charset=utf8' });
res.write(fs.readFileSync('./static/404.html'), 'utf-8');
res.end();
},
'/favicon.ico': (req, res) => {
render(res, './static/favicon.ico', 'image/x-icon');
},
};
function readStaticFile(req, res) {
const url = new URL(req.url, 'http://127.0.0.1:3000');
const pathname = path.join(__dirname, '/static', url.pathname);
if (fs.existsSync(pathname)) {
render(res, pathname, mime.getType(path.extname(pathname)));
return true;
}
return false;
}