上一章讲到怎么样用原生node.js来获取GET、POST(urlencoded,formData)的参数,这一次我们更进一步,讲一下以下的点:

1.压缩(zlib)

2.流(stream)

3.路由


一、压缩

所有网站其实在发送到我们的客户端的时候,数据都是经过压缩的,不然会造成大量的流量损失,流量可都是钱啊~~~

node里面有一个模块叫zlib,是专门用来压缩数据的,而我们最常用的就是gzip

const zlib = require('zlib');
//创建gz对象,之后就可以对流进行压缩处理了
let gz = zlib.createGzip();

二、流

为什么要用流处理呢?例如之前的写法,fs.readFile是读取完整个文件才把整个文件的data输出的,这样就会造成一个机器资源使用不充分的问题:

一开始读取文件的时候,磁盘在高速工作,但是带宽却空闲着,

之后读取完文件后,带宽在忙碌传输,磁盘却空闲了。

用流来处理,就可以做到“磁盘读到多少就用带宽传多少”,充分利用服务器的资源

//创建一个读取流
let rs = fs.createReadStream(`www${pathname}`);
let gz = zlib.createGzip();
//书写响应头,告诉浏览器我们的数据格式是经过压缩的gzip
res.setHeader('Content-Encoding','gzip');
//读取流先传给gz,再传给响应流
rs.pipe(gz).pipe(res);
rs.on('error',err=>{
//如果错误,要把之前的响应头去掉,不然浏览器会解析错误
res.removeHeader('Content-Encoding');
res.writeHeader(404);
res.write('not found!!');
res.end();
})

三、路由

所谓路由,就是接口的地址入口,我们大可以这样写:

switch(pathname){
case '/login':
//...
break;
case '/reg':
//...
break;
default:
//...
break;
}

不过这样写,导致路由和功能代码严重的耦合在一起,这显然不是我们想要的

node给我们提供了一个叫EventEmitter的东西,实现了在js的响应式编程

因为node.js的引用是单例的,因此我们可以先创建一个module作为全局的EventEmitter,router.js

const Event = require('events').EventEmitter;

module.exports = new Event();

在server.js那加入EventEmitter的触发:

const http = require('http');
const fs = require('fs');
const router = require('./libs/router');
const url = require('url');
const zlib = require('zlib');
//在'./router/Users'上面注册了一些接口
require('./router/Users'); http.createServer((req,res)=>{
let {pathname,query}=url.parse(req.url,true);
req.query = query;
res.send = msg=>{
if(typeof msg!="string"&&!(msg instanceof Buffer)){
msg = JSON.stringify(msg);
}
res.write(msg);
}
//router.emit会触发对应的接口,如果事先有注册对应的接口返回true,否则返回false,我们就认为这个请求是在请求文件
if(!router.emit(pathname,req,res)){
let rs = fs.createReadStream(`www${pathname}`);
let gz = zlib.createGzip();
res.setHeader('Content-Encoding','gzip');
rs.pipe(gz).pipe(res);
rs.on('error',err=>{
res.removeHeader('Content-Encoding');
res.writeHeader(404);
res.write('not found!!');
res.end();
})
}
}).listen(8088);

做完这些,我们就可以在多个模块来“注册”接口了

const router = require('../../libs/router.js');

let users = {
rick : 123456
};
//注册一个叫'/login'的接口,在这里我们还可以添加上一篇博文的东西,接收GET、POST的参数,这里我只写了接收URL上的参数
router.on('/login',(req,res)=>{
let {name,pass} = req.query;
if(!users[name]){
res.send({code:1,msg:'user not found!'})
}else if(users[name]!=pass){
res.send({code:1,msg:'username or password is wrong'})
}else{
res.send({code:0,msg:'success'})
}
res.end();
})

node.js原生后台进阶(二)的更多相关文章

  1. node.js原生后台进阶(一)

    后台对于我们前端来说可能真的有点陌生,下面我来理清一下思绪吧. 一个基本的后台要求有如下功能: 1.与前端的数据交互 2.操作数据库(增删改查) 3.操作服务器文件(也大概是增删改查) 本次我们先讨论 ...

  2. Node.js原生及Express方法实现注册登录原理

    由于本文只是实现其原理,所以没有使用数据库,只是在js里面模拟数据库,当然是种中还是需要用数据库的. 1.node.js原生方法 ①html页面,非常简单,没有一丝美化~我们叫它user.html & ...

  3. 用Node.js原生代码实现静态服务器

    ---恢复内容开始--- 后端中服务器类型有两种 1. web服务器[ 静态服务器 ] - 举例: wamp里面www目录 - 目的是为了展示页面内容 - 前端: nginx 2. 应用级服务器[ a ...

  4. 使用Node.js原生API写一个web服务器

    Node.js是JavaScript基础上发展起来的语言,所以前端开发者应该天生就会一点.一般我们会用它来做CLI工具或者Web服务器,做Web服务器也有很多成熟的框架,比如Express和Koa.但 ...

  5. Node.js学习笔记(二):模块

    模块是 Node.js 应用程序的基本组成部分,文件和模块是一一对应的.一个 Node.js 文件就是一个模块,这个文件可能是 JavaScript 代码.JSON 或者编译过的 C/C++ 扩展. ...

  6. 使用Node.js作为后台进行爬虫

    看了一遍又一遍Node.js但是没过多久就又忘了,总想找点东西来练练手,就发现B站首页搜索框旁边的GIF图特别有意思,想着是不是可以写一个小Node.js项目把这些图全部扒下来,于是带着复习.预习与探 ...

  7. Node.js 蚕食计划(二)—— 使用 http 模块搭建 Web 服务器

    Node.js 开发的目的就是为了用 JavaScript 编写 Web 服务器程序 这次就来介绍用 http 模块搭建服务器 一.项目构建 每个 Node 程序都可以看作一个模块,而每个模块都应该有 ...

  8. node.js学习笔记(二)——回调函数

    Node.js 异步编程的直接体现就是回调. 那什么是回调呢?回调指的是将一个函数作为参数传递给另一个函数,并且通常在第一个函数完成后被调用.需要指明的是,回调函数不是由该函数的实现方直接调用,而是在 ...

  9. 编写Node.js原生扩展

    Node.js是一个强大的平台,理想状态下一切都都可以用javascript写成.然而,你可能还会用到许多遗留的库和系统,这样的话使用c++编写Node.JS扩展会是一个不错的注意. 以下所有例子的源 ...

随机推荐

  1. ubuntu 桌面操作系统安装WPS办公软件的方法

    1.打开ubuntu系统自带的firefox软件 2.打开linux.wps.cn,并点击立即下载 3. 点击下载deb安装包 4.进入下载目录,sudo dpkg -i wps-office_10. ...

  2. [UOJ#461]新年的Dog划分[二分图染色、二分]

    题意 给你一张无向连通图,你并不知道有哪些边,你首先要回答这张图是否是二分图,如果是,回答这张图黑白染色过后的任意一个点集.你需要在2000次询问内找到结果,每次你可以询问原图中一个边集删掉后是否还连 ...

  3. WPF DataGrid列设置为TextBox控件的相关绑定

    在wpf的DataGrid控件中,某一列的数据模板为TextBox控件的话,绑定Text="{Binding TxtSn, UpdateSourceTrigger=PropertyChang ...

  4. GitLab篇之Linux下环境搭建

    之前公司一直在使用微软的VSS和SVN做为源代码管理工具,考虑到VSS和SVN的局限性,个人一直建议我们应该采用Git来管理我们的源代码.Git的好处不多说相信大家也都知道的.Git不仅仅是一个源代码 ...

  5. UE4添加植被Foliage Type

    在UE4中的地形渲染上不可避免的需要添加植被,而如果采取手动添加StaticMesh植被的方式则会浪费大量的时间精力. UE4提供了一种批量添加地面植被类型的方式Foliage Type.在编辑器内容 ...

  6. vector 简介

    vector简介 vector是STL中最常见的容器,它是一种顺序容器,支持随机访问.vector是一块连续分配的内存,从数据安排的角度来讲,和数组极其相似, 不同的地方就是:数组是静态分配空间,一旦 ...

  7. MyBatis3-动态SQL语句

    MyBatis的动态SQL语句是基于OGNL表达式的.可以方便的在SQL语句中实现某些逻辑,总体说来MyBatis动态SQL语句主要有以下几类: 1.if语句(简单的条件判断). 2.choose(w ...

  8. 使用git进行代码的推送

    首先是对于锐捷墙的问题,登陆github有时可以有时又连不上,网络又非常慢,所以用了十足的耐心才fork完了代码库.链接https://github.com/niconiconiconi/hellow ...

  9. (Alpha)Let's-Chronos分数分配规则

    Requirement: 每个团队开一个讨论会,协商讨论团队贡献分的分配方式.每个团队的团队贡献分为50分/人.每个人分数不能相同,请详细说明分数的分配规则. 为了完成此次的团队贡献分的分配任务,我们 ...

  10. (第三周)使用visual studio 2015进行单元测试

    Microsoft visual studio是目前最流行的windows平台应用程序的集成开发环境.最新版本为 Visual Studio 2015 .Visual Studio 2015 包含许多 ...