用nodehttp模块搭建服务器,已经用于项目实践和开发。经过深入学习,对node搭建http服务器有了新的认识和认识。写这篇文章来总结和列出对gzip压缩的支持Cachesupport/controlyargswithautomationGzipGZIP最初是由Jean-loupGailly和MarkAdler创建的,用于UNIX系统上的文件压缩。我们在Linux中经常使用后缀为.gz的文件,它们是GZIP格式的。现在它已经成为一种非常普遍的数据压缩格式,或者说是一种文件格式,在互联网上使用。HTTP协议上的GZIP编码是一种用来提高WEB应用程序性能的技术。高流量的WEB站点通常使用GZIP压缩技术来让用户体验更快的速度。这通常是指安装在WWW服务器中的功能。当有人访问本服务器中的网站时,服务器中的此功能会将网页内容进行压缩,并传送到来访的电脑浏览器中显示。通常,纯文本内容可以压缩到原始大小的40%。这样传输速度快,效果是点击网址后很快显示出来。当然,这样也会增加服务器的负载。服务器端一般都会安装这个功能模块。HTTP请求头Accept-Encoding会告知客户端客户端可以理解的内容编码方式——通常是某种压缩算法。通过内容协商,服务器将选择客户端提出的一种方法,使用它并在响应消息的Content-Encoding标头中将选择通知客户端。Accept-Encoding:gzip,deflate,br//当前请求支持gzip,default,brContent-Encoding:gzip//当前内容压缩格式为gzip,可以使用命令行设置请求Accept-Encodingheadercurl-v-H"Accept-Encoding:deflate"http://localhost:8080/msg.txthttpwithGzipfunctionrequest(req,res){let{pathname}=url.parse(req.url);///msg.txt//D:\vipcode\201801\16.http\msg.txtletfilepath=path.join(__dirname,pathname);try{//await只在异步函数中有效letstatObj=awaitstat(filepath);//可以根据不同的文件内容类型返回不同的Content-Typeres.setHeader('Content-Type',mime.getType(pathname));//为了兼容不同的浏览器,node将所有的请求头都转为小写letacceptEncoding=req.headers['accept-encoding'];//内容协商if(acceptEncoding){if(acceptEncoding.match(/\bgzip\b/)){//服务器告诉客户端我用什么压缩方式压缩res.setHeader('Content-Encoding','gzip');fs.createReadStream(文件路径).pipe(zlib.createGzip()).pipe(res);}否则我f(acceptEncoding.match(/\bdeflate\b/)){res.setHeader('Content-Encoding','deflate');fs.createReadStream(文件路径).pipe(zlib.createDeflate()).pipe(res);}else{fs.createReadStream(filepath).pipe(res);}}else{fs.createReadStream(文件路径).pipe(res);}}catch(e){res.statusCode=404;重发();}}根据req.headers['accept-encoding']的类型压缩请求的静态资源;fs.createReadStream(文件路径).pipe(zlib.xxx()).pipe(res);tip:可以在util模块中使用promisify,将异步方法转为返回promise的方法(节点v8及以上)let{promisify}=require('util');让stat=promisify(fs.stat);缓存可以减少对服务器的请求,加快请求效率lastModifyetageexpireslastModify使用最后修改时间判断缓存是否可用);}else{letifModifiedSince=req.headers['if-modified-since'];//请求头资源最后修改时间letLastModified=stat.ctime.toGMTString();//文件最后修改时间if(ifModifiedSince==LastModified){//如果相等则返回304res.writeHead(304);重发('');}else{returnsend(req,res,filepath,stat);}}});ETag是entitytag的缩写,是根据实体内容生成的哈希字符串,可以标识资源的状态。当资源发生变化时,ETag也会发生变化。ETag由Web服务器生成并发送给浏览器客户端。fs.stat(file,(err,stat)=>{if(err){sendError(err,req,res,file,stat);}else{letifNoneMatch=req.headers['if-none-match'];让etag=crypto.createHash('sha1').update(stat.ctime.toGMTString()+stat.size).digest('hex');if(ifNoneMatch){if(ifNoneMatch==etag){res.writeHead(304);res.end();}else{send(req,res,file,etag);}}else{send(req,res,file,etag);}}});设置服务器响应头字段过期res.setHeader('Expires',expires.toUTCString());res.setHeader('Cache-Control','max-age=60');automaticmacnew自动化shell脚本和windows的区别$touchhello.sh$chmod+xhello.sh$./hello.shinstallyargsyargsmodule可以解决如何处理命令行参数。它还需要安装。npmiyargs--saveedithello.shletyargs=require('yargs');//可以帮助我们解析命令行参数,将参数数组转为对象形式//-n--nameletargv=yargs.options('n',{alias:'name',//aliasdemand:true,//requireddefault:'yuanyuan',description:'请输入你的名字'}).usage('hellp[opitons]').help()//指定帮助信息.example('hello-nameyuanyuan','执行hello命令,然后传入name参数为yuanyuan').alias('h','help').argv;console.log(argv);console.log('你好'+argv.name);添加package.json,添加如下内容{"name":"hello","bin":{"hello":"hello"}}执行npmlink命令。$npmlink可以直接执行hello命令
