静态资源服务器功能
/** * 静态服务器功能:核心模块HTTP * 初步实现服务器功能 */ const http = require('http'); //创建服务器实例对象 let server = http.createServer(); //绑定请求事件 server.on('request',(req,res) => { res.end('hello'); }); //监听端口 访问地址:localhost:3000 server.listen(3000); //========================================= http.createServer((req,res) => { res.end('ok'); }).listen(3000,'196.167.0.8',() => { //此时不能再用localhost访问了,只能用IP地址:3000 console.log('running...'); });
/** * 处理请求路径的分发 * 因为访问localhost:3000、localhost:3000/index.html、localhost:3000/about.html等页面时,显示内容都一样 * 1.req对象是Class:http.IncomingMessage的实例对象 * 2.res对象是Class:http.ServerResponse的实例对象 */ const http = require('http'); http.createServer((req,res) => { //req.url可以获取URL中的路径(端口之后的路径) //res.end(req.url); if(req.url.startsWith('/index')){ //write向客户端相应内容,可多次写回,拼写到一起 res.write('hello'); res.write('welcome'); //end用来完成响应,可以带参数也可以不带,只能执行一次 res.end('index'); }else if(req.url.startsWith('/about')){ res.end('about'); }else{ res.end('no content'); } }).listen(3000,'196.167.0.8',() => { //此时不能再用localhost访问了,只能用IP地址:3000 console.log('running...'); });
/** * 响应完整的页面信息,先创建多个文件,利用路径分发功能分别对不同页面进行响应 */ const http = require('http'); const path = require('path'); const fs = require('fs'); //根据路径读取文件的内容,并且相应到浏览器 //抽取出来作为单独的一个方法 let readFile = (url,res) => { fs.readFile(path.join(__dirname,url),'utf8',(err,fileContent) => { if(err){ res.end('server error'); }else{ res.end(fileContent); } }); } //处理路径分发 http.createServer((req,res) => { if(req.url.startsWith('/index')){ readFile('index.html',res); }else if(req.url.startsWith('/about')){ readFile('about.html',res); }else if(req.url.startsWith('/list')){ readFile('list.html',res); }else{ //设置相应类型和编码,否则没有响应投不能正常跳转 res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf8'}); res.end('404 not found'); } }).listen(3000,'196.167.0.8',() => { //此时不能再用localhost访问了,只能用IP地址:3000 console.log('running...'); });
随着页面分支越来越多,上述方式不够灵活,应该根据url去获取这个文件(利用req.url获取到的是端口号后面的路径)
/** * 路径分发的改进 */ const http = require('http'); const path = require('path'); const fs = require('fs'); //引入mime模块,作用就是根据url的后缀,返回对应的Content-Type,或者你传递Content-Type,它返回对应的文件类型的后缀 //安装mime模块:npm install mime --save const mime = require('mime'); //处理路径分发 http.createServer((req,res) => { fs.readFile(path.join(__dirname,req.url),(err,fileContent) => { if(err){ //没有找到对应文件 //设置响应头信息,避免出现乱码 res.writeHead(404,{ 'Content-Type':'text/plain;charset=utf8' }); //res.writeHead(404, { 'Content-Type': 'text/plain; charset=utf8'}); res.end('页面丢失了'); }else{ //获取请求文件的后缀 //默认类型: //let dType = 'text/html'; //let ext = path.extname(req.url); //console.log(ext); //console.log(mime[ext]); //console.log(mime.getType(path.join(__dirname,req.url))); //如果哟请求的文件后缀合理,就获取到标准的响应格式 //如果mime里面存在这个后缀,则覆盖默认的后缀类型 //这种做法不行,一直处在默认类型,进不了这个循环 /* if(mime[ext]){ dType = mime[ext]; } */ //mime.getType(filePath) let dType = mime.getType(path.join(__dirname,req.url)); //如果是文本类型,则需要设置其编码类型 if(dType.startsWith('text')){ dType += ';charset=utf8' } //设置响应头信息 res.writeHead(200,{'Content-Type':dType}); res.end(fileContent); } }); }).listen(3000,() => { console.log('running...'); });
为了对静态资源服务器这个功能进行优化,可以将这部分功能抽取成一个独立的模块,方便以后使用。
/** * 抽取模块:01.js文件 */ const http = require('http'); const path = require('path'); const fs = require('fs'); const mime = require('mime'); //root表示文件的根路径 exports.staticServer = (req,res,root) => { fs.readFile(path.join(root,req.url),(err,fileContent) => { if(err){ //没有找到对应文件 //设置响应头信息,避免出现乱码 res.writeHead(404,{ 'Content-Type':'text/plain;charset=utf8' }); //res.writeHead(404, { 'Content-Type': 'text/plain; charset=utf8'}); res.end('页面丢失了'); }else{let dType = mime.getType(path.join(__dirname,req.url)); //如果是文本类型,则需要设置其编码类型 if(dType.startsWith('text')){ dType += ';charset=utf8' } //设置响应头信息 res.writeHead(200,{'Content-Type':dType}); res.end(fileContent); } }); }
/** * 测试模块:02.js文件 */ const http = require('http'); const path = require('path'); const ss = require('./03.js'); http.createServer((req,res) => { ss.staticServer(req,res,path.join(__dirname)); }).listen(3000,() => { console.log('running...'); });