Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用,和丰富的 HTTP 工具。
使用 Express 可以快速地搭建一个完整功能的网站。
Express 框架核心特性:
-
可以设置中间件来响应 HTTP 请求。
-
定义了路由表用于执行不同的 HTTP 请求动作。
-
可以通过向模板传递参数来动态渲染 HTML 页面。
接下来要实现的极简版express功能,只实现框架核心特性中的第二条:定义了路由表用于执行不同的 HTTP 请求动作。
1、node.js Web模块原生写法
const http = require('http');
const path = require('path');
const fs = require('fs')
// 创建服务器
http.createServer((req, res) => {
console.log('接收到一个请求'+req.url);
//res.end('hello')
const { url, method } = req;
if (url === '/' && method === 'GET') {
// 从文件系统中读取请求的文件内容
const filePath = path.resolve('./index.html');
console.log(filePath);
fs.readFile(filePath, (error, data) => {
if (error) {
res.statusCode = 500;
res.setHeader('content-type', 'text/plain;charset=utf-8');
res.end('服务器内部错误');
return;
}
// HTTP 状态码: 200 : OK
res.statusCode = 200;
res.setHeader('content-type','text/html');
// res.setHeader('content-type', 'text/plain;charset=utf-8');
// 发送响应数据
res.end(data);
})
} else if (url === '/user' && method === 'GET') {
res.statusCode = 200;
res.setHeader('content-type', 'application/json; charset=utf-8')
res.end(JSON.stringify([{ name: '张三', age: 20 }]));
} else if (req.headers.accept.indexOf('image/*') !== -1 && method === 'GET') {
fs.createReadStream(path.resolve("."+url)).pipe(res);
}
}).listen(3000)
2、Express写法
安装 Express
安装 Express 并将其保存到依赖列表中:
$ npm install express --save
const express = require('express');
const path = require('path');
const fs = require('fs')
const app = new express();
app.get('/', (req, res) => {
const filePath = path.resolve('./index.html');
fs.readFile(filePath, (error, data) => {
if (error) {
res.statusCode = 500;
res.setHeader('content-type', 'text/plain;charset=utf-8');
res.end('服务器内部错误');
return;
}
res.statusCode = 200;
res.setHeader('content-type', 'text/html');
// res.setHeader('content-type', 'text/plain;charset=utf-8');
res.end(data);
})
})
app.get('/user', (req, res) => {
res.statusCode = 200;
res.setHeader('content-type', 'application/json; charset=utf-8')
res.end(JSON.stringify([{ name: '张三', age: 20 }]));
})
app.listen(3000);
3、自己实现的简版express
const http = require('http');
const url = require('url');
//存储路由
const router = [];
class Application {
get(path, handler) {
router.push({ path, method: 'get', handler })
}
listen() {
http.createServer((req,res)=>{
// 解析请求,包括文件名
const {pathname} = url.parse(req.url,true);
console.log(url.parse(req.url,true));
for (const route of router) {
//遍历路由匹配pathname,执行回调
if(route.path === pathname){
route.handler(req,res);
return;
}
}
}).listen(...arguments)
}
}
//模块覆盖导出
module.exports = function(config){
return new Application();
}
使用
const myexpress = require('./myexpress')
const path = require('path');
const fs = require('fs')
const app = new myexpress();
app.get('/', (req, res) => {
const filePath = path.resolve('./index.html');
fs.readFile(filePath, (error, data) => {
if (error) {
res.statusCode = 500;
res.setHeader('content-type', 'text/plain;charset=utf-8');
res.end('服务器内部错误');
return;
}
res.statusCode = 200;
res.setHeader('content-type', 'text/html');
// res.setHeader('content-type', 'text/plain;charset=utf-8');
res.end(data);
})
})
app.get('/user', (req, res) => {
res.statusCode = 200;
res.setHeader('content-type', 'application/json; charset=utf-8')
res.end(JSON.stringify([{ name: '张三', age: 20 }]));
})
app.listen(3001);