上一节
(末尾含完整程序)
上一节做了对get,post请求的处理,这一节做静态资源访问。
处理静态资源访问的原因
- 如果客户端请求的数据是静态页面或者资源文件,就需要处理一下,返回对应文件的数据,如果不处理的话,就会按照路由匹配处理,这样就是匹配不到,就会404了。
- 比如在html文件中引入了css文件,所以也要去请求这个css文件,同样不做静态资源访问,也会当路由处理
开始
- 首先配置一下静态资源的目录名称,一般大家的目录名称以static和public比较多,这里将目录名称设为默认的static,当然也可以动态修改,相当于设置了default。
let server = () => {
let G = {
_post: {},
_get: {},
staticPath: 'static'
}
let app = function (req, res) {...}
app.get = function (str, cb) {...}
app.post = function (str, cb) {...}
// 配置静态web服务目录
app.static = function (staticPath) {
G.staticPath = staticPath
}
return app
}
为G对象新增一个staticPath属性,存储静态目录名称,给app函数新增一个static方法,用来动态修改静态资源目录名称,参数字符串的目录名称
- 封装处理静态资源的函数
引入fs,path模块
const path = require('path')
const fs = require('fs')
function initStatic(req, res, staticPath) {
// 获取请求的路径 /css/style.css /login
// 包括路由和静态资源文件
let pathname = url.parse(req.url).pathname
// 使用path模块的extname,获取请求路径的后缀名
let extname = path.extname(pathname)
// 判断一下后缀名存不存在,没有后缀名extname 就是空,如果非空就访问静态资源文件
if (extname) {
try {
/**
* 以异步的方法读取静态资源文件,app.js和静态资源是同一级的目录,所以使用了'./'
* - app.js
* - public/static
* 所以如,文件的路径就是'./static/css/style.css’
*/
let data = fs.readFileSync('./' + staticPath + pathname)
if (data) {
/**
* 如果获取到了,执行
* 静态资源的文件格式多种多样,如.css,.js.jpg,.json等,所以响应头的类型就要做特殊处理了,返回正确与之对应的文件类型
* 这里也就封装了一个getFileMine方法(下面介绍),用于获取文件的类型
* 然后把响应的文件类型动态拼接到响应头就行了
*/
let mime = getFileMine(extname)
res.writeHead(200, { "Content-Type": '' + mime + ";charset=utf-8" })
// 最后返回数据
res.end(data)
}
} catch (error) {
console.log(error);
}
}
}
- getFileMine方法获取对应文件的返回类型
因为文件后缀名繁多,所以我把数据放到一个json文件中了,为了访问速度放在了码云,直接复制即可https://gitee.com/solitary-cloud/basic-notes-of-node/blob/master/mime.json
目录结构
data\
--mime.json
static\
modules\
--route.js
app.js
// 参数就是文件后缀名
function getFileMine(extname) {
// 读取mime.json文件,并转换成对象格式
var data = fs.readFileSync('./data/mime.json')
let mineObj = JSON.parse(data.toString())
// 然后返回文件类型
return mineObj[extname]
}
最后在app函数中配置一下一下
let app = function (req, res) {
changeRes(res);
//配置静态web服务
initStatic(req, res, G.staticPath);
...
}
app.js文件里使用route.js
const http = require('http')
const app = require('./modules/route')
http.createServer(app).listen(3000);
// 配置静态资源访问
app.static("static")
// 配置路由
app.get('/login', function (req, res) {
})
app.post('/doLogin', function (req, res) {
console.log(req.body);
res.send(req.body)
})
app.get('/', function (req, res) {
res.send("home")
})
ok,基本完成了
完整代码(route.js)
const url = require('url')
const path = require('path')
const fs = require('fs')
/**
*
* @param {obj} res 扩展res
*/
function changeRes(res) {
res.send = (data) => {
res.writeHead(200, {
"Content-Type": "text/html;charset=utf-8"
})
res.end(data)
}
}
/**
* 根据后缀名获取文件类型
* @param {string} extname 文件的后缀名
* @returns
*/
function getFileMine(extname) {
// 使用promise异步获取
// return new Promise((resolve, reject) => {
// fs.readFile('./data/mime.json', (err, data) => {
// if (err) {
// console.log(err);
// return;
// }
// let mineObj = JSON.parse(data.toString())
// resolve(mineObj[extname])
// })
// })
var data = fs.readFileSync('./data/mime.json')
let mineObj = JSON.parse(data.toString())
return mineObj[extname]
}
function initStatic(req, res, staticPath) {
let pathname = url.parse(req.url).pathname
let extname = path.extname(pathname)
console.log(extname);
if (extname) {
try {
let data = fs.readFileSync('./' + staticPath + pathname)
if (data) {
let mime = getFileMine(extname)
res.writeHead(200, { "Content-Type": '' + mime + ";charset=utf-8" })
// console.log(pathname);
res.end(data)
}
} catch (error) {
console.log(error);
}
}
}
let server = () => {
let G = {
_post: {},
_get: {},
staticPath: 'static'
}
let app = function (req, res) {
changeRes(res);
initStatic(req, res, G.staticPath);
let pathname = url.parse(req.url).pathname;
let method = req.method.toLowerCase();
let extname = path.extname(pathname);
if (!extname) { //如果有后缀名用静态web处理
if (G['_' + method][pathname]) {
if (method == "get") {
G['_' + method][pathname](req, res);
} else {
let postData = '';
req.on('data', (chunk) => {
postData += chunk;
})
req.on('end', () => {
req.body = postData;
G['_' + method][pathname](req, res);
})
}
} else {
res.writeHead(404, { 'Content-Type': 'text/html;charset="utf-8"' });
res.end('页面不存在');
}
}
}
app.get = function (str, cb) {
G._get[str] = cb
}
app.post = function (str, cb) {
G._post[str] = cb
}
app.static = function (staticPath) {
G.staticPath = staticPath
}
return app
}
module.exports = server()
网友评论