HTTP,URL,FS 模块搭建一个静态WEB服务器
WEB服务器:
一般指网站服务器,是指驻留在因特网上某种类型计算机的程序,可以向浏览器等Web 客户端提供文档,也可以放置网站文件让全世界浏览,还可以放置数据文件,让全世界下载,目前最主流的Web服务器有 Apache,Nginx,IIS等。
NodeJS 创建一个WEB服务器,
可以让我们访问Web服务器上面的网站
可以让我们下载Web服务器上面的文件
把static 目录下的 html,css,js,json等静态资源放在服务器上被浏览器读取
1,通过 fs 模块读取static 目录下的所有文件,需要现获取地址
const http = require('http'); const fs = require('fs') http.createServer(function (request, response) { //1,通过fs模块读取static目录下的文件 let pathname = request.url //先获取地址 pathname=pathname=='/'?'/index.html':pathname //根目录下定位到首页 console.log(path) if (pathname!='/favicon.ico'){//过滤favicon的请求再读取 fs.readFile('./static'+pathname,(err,data)=>{ if(err){ response.writeHead(404, { 'Content-Type': 'text/html;charset="utf-8"' }); response.end('<h3>404</h3>'); } else{ response.writeHead(200, { 'Content-Type': 'text/html;charset="utf-8"' }); response.end(data); } }) } }).listen(8081);
浏览器中地址栏中输入:http://127.0.0.1:8081/login.html ,会打印 /login.html 和 /favicon.ico,输入http://127.0.0.1:8081/index.html 会打印 /index.html 和 /favicon.ico ,所以可以过滤掉 /favicon.ico 这个请求,并且,当路径为 http://127.0.0.1:8081 时,path 为根目录 / ,可以定为到首页。
但这时会有报错:
json文件以及页面样式文件等等都无法加载,这是因为,我们读取的文件类型都是 text/html ,css和js等文件都以这种文件类型读取是不合适的,需要做相应的修改
这里需要根据文件后缀修改
2,根据后缀名设置不同的文件类型:
引入path模块,通过 paht模块的 extname() 方法可以获取文件后缀名
const http = require('http'); const fs = require('fs') const path = require('path') http.createServer(function (request, response) { //1,通过fs模块读取static目录下的文件 let pathname = request.url //先获取地址 pathname=pathname=='/'?'/index.html':pathname //根目录下定位到首页 //console.log(path) let ext=path.extname(pathname) //获取文件后缀名 console.log(ext) if (pathname!='/favicon.ico'){//过滤favicon的请求再读取 fs.readFile('./static'+pathname,(err,data)=>{ if(err){ response.writeHead(404, { 'Content-Type': 'text/html;charset="utf-8"' }); response.end('<h3>404</h3>'); } else{ response.writeHead(200, { 'Content-Type': 'text/html;charset="utf-8"' }); response.end(data); } }) } }).listen(8081);
对于JSON文件,只需要保留.json,使用 url 模块,解析 url
接着定义一个设置文件类型的方法,并暴露出去,在读取文件时调用:
getMime.js :
exports.getMime=function(ext){ switch(ext){ case '.html': return 'text/html' case '.css': return 'text/css' case '.js': return 'text/javascript' default: return 'text/html' } }
web.js 外部调用这个模块中的 getMime 方法
const http = require('http'); const fs = require('fs') const path = require('path') const url = require('url') const util = require('./utils/util') http.createServer(function (request, response) { //1,通过fs模块读取static目录下的文件 let pathname = url.parse(request.url).pathname //先获取地址 //console.log(pathname) pathname=pathname=='/'?'/index.html':pathname //根目录下定位到首页 //console.log(pathname) /** /index.html */ let ext=path.extname(pathname) //获取文件后缀名 //console.log(ext) /**.html */ let mime = util.getMime(ext) //获取文件类型 //console.log(mime) /** text/html */ if (pathname!='/favicon.ico'){//过滤favicon的请求再读取 fs.readFile('./static'+pathname,(err,data)=>{ if(err){ response.writeHead(404, { 'Content-Type': 'text/html;charset="utf-8"' }); response.end('<h3>404</h3>'); } else{ response.writeHead(200, { 'Content-Type': `${mime};charset="utf-8"` }); //es6模板字符串方式 //response.writeHead(200, { 'Content-Type': '' + mime + ';charset="utf-8"' }); //字符串拼接方式 response.end(data); } }) } }).listen(8081);
现在可以加载出 css , js 文件了
为了支持更多文件类型的加载,引入一个 mime.json 文件,在设置文件类型的模块中读取这个文件:
mime.json
getMime.js 模块中需要异步读取这个文件,有两种方式,
方式一:通过 promise,返回一个promise对象,在web.js 中使用 async 和 await 读取返回的promise的返回值,
util 模块暴露出的 getMime 方法
const fs = require('fs') exports.getMime = function (ext) { return new Promise((resolve,reject)=>{ fs.readFile('./utils/mime.json',(err,data)=>{ //注意路径相对于根目录 if(err){ console.log("读取失败") reject(err) } else{ //console.log(data); //buffer //console.log(data.toString()) //".css":"text/css" //console.log(JSON.parse(data.toString())) // '.css':'text/css' //console.log(JSON.parse(data.toString())[ext]) //text/css let mime = JSON.parse(data.toString())[ext] resolve(mime) } }) }) }
外部调用:
const http = require('http'); const fs = require('fs') const path = require('path') const url = require('url') const util = require('./utils/util') http.createServer(function (request, response) { let pathname = url.parse(request.url).pathname //先获取地址 pathname=pathname=='/'?'/index.html':pathname //根目录下定位到首页 let ext=path.extname(pathname) //获取文件后缀名 if (pathname!='/favicon.ico'){//过滤favicon的请求再读取 fs.readFile('./static'+pathname,async (err,data)=>{ if(err){ response.writeHead(404, { 'Content-Type': 'text/html;charset="utf-8"' }); response.end('<h3>404</h3>'); } else{ let mime = await util.getMime(ext) //获取文件类型 response.writeHead(200, { 'Content-Type': `${mime};charset="utf-8"` }); response.end(data); } }) } }).listen(8081);
方式二,直接使用 fs.readFileSync 同步读取文件,读取完成才进行下一步操作:
const fs = require('fs') exports.getMime = function (ext) { let data=fs.readFileSync('./utils/mime.json'); //同步方法,没有回调 let mime = JSON.parse(data.toString())[ext] return mime; }
外部调用:
const http = require('http'); const fs = require('fs') const path = require('path') const url = require('url') const util = require('./utils/util') http.createServer(function (request, response) { let pathname = url.parse(request.url).pathname //先获取地址 pathname=pathname=='/'?'/index.html':pathname //根目录下定位到首页 let ext=path.extname(pathname) //获取文件后缀名 if (pathname!='/favicon.ico'){//过滤favicon的请求再读取 fs.readFile('./static'+pathname,(err,data)=>{ if (err) { response.writeHead(404, { 'Content-Type': 'text/html;charset="utf-8"' }); response.end('<h3>404</h3>'); } else { let mime = util.getMime(ext) //获取文件类型 response.writeHead(200, { 'Content-Type': `${mime};charset="utf-8"` }); response.end(data); } }) } }).listen(8081);
两种方式,都可以使浏览器加载各种类型资源文件:
封装创建静态web服务
web.js
const fs = require('fs') const path = require('path') const url = require('url') let getMime = function (ext) { let data = fs.readFileSync('./mime.json'); //同步方法,没有回调 let mime = JSON.parse(data.toString())[ext] return mime; } module.exports = function staticWeb(req,res,staticPath){ let pathname = url.parse(req.url).pathname //先获取地址 pathname = pathname == '/' ? '/index.html' : pathname //根目录下定位到首页 let ext = path.extname(pathname) //获取文件后缀名 if (pathname != '/favicon.ico') {//过滤favicon的请求再读取 fs.readFile(staticPath + pathname, (err, data) => { if (err) { res.writeHead(404, { 'Content-Type': 'text/html;charset="utf-8"' }); res.end('<h3>404</h3>'); } else { let mime = getMime(ext) //获取文件类型 res.writeHead(200, { 'Content-Type': `${mime};charset="utf-8"` }); res.end(data); } }) } }
test.js ,只需要传入 req , res , 和静态资源目录即可:
const http = require('http'); const staticWeb = require('./web') http.createServer(function (request, response) { staticWeb(request,response,'./static') }).listen(8081);