上一章讲到怎么样用原生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. 分享一下个人学PS的过程

    得知Photoshop这款软件是在上大学的时候,2010年.学校学生会的科技部纳新,要求新人会PPT.word.Excel和Photoshop.当时有一个Photoshop大神,成为了学生会科技部的主 ...

  2. nova状态同步

    服务初始化阶段 nova-compute服务启动时调用manager中的host初始化函数 self.manager.init_host() 在host初始化函数中完成如下操作: #初始化libvir ...

  3. effective c++ 笔记 (5-8)

    //---------------------------15/03/26---------------------------- //#5    了解c++默默编写并调用哪些函数 { /* c++会 ...

  4. flask_admin 笔记三 客户化视图

    客户化视图1, model数据模型参数配置1)配置全局参数内置的ModelView类很适合快速入门. 但是,您需要配置其功能以适合您的特定型号. 这是通过设置ModelView类中提供的配置属性的值来 ...

  5. HTML 表格实例

    1.表格这个例子演示如何在 HTML 文档中创建表格. <p>每个表格由 table 标签开始.</p><p>每个表格行由 tr 标签开始.</p>&l ...

  6. CMake与MSVC工程化实践

    CMake与MSVC工程化实践 CMake基础 cmake无疑是最流行的c++跨平台构建工具之一,关于cmake入门指南这里不再赘述,官方文档是最好的参考,这里通过一个例子简述构建一个工程常用的函数和 ...

  7. Unity特殊路径

    Resources: Resources文件可以在根目录下,也可以在子目录下,只要叫Resources就好.Resources目录下所有资源将被打包进游戏存放资源的archive中,Resources ...

  8. 详细聊聊k8s deployment的滚动更新(二)

    一.知识准备 ● 本文详细探索deployment在滚动更新时候的行为 ● 相关的参数介绍:   livenessProbe:存活性探测.判断pod是否已经停止   readinessProbe:就绪 ...

  9. B1004. 成绩排名

    这一题总算是把C++的重载活学活用了一回,节省了很多脑细胞. #include<bits/stdc++.h> using namespace std; struct student{ st ...

  10. HyperLedger Fabric 学习思路分享

    HyperLedger Fabric 学习思路分享 HyperLedger Fabric最初是由Digital Asset和IBM公司贡献的.由Linux基金会主办的一个超级账本项目,它是一个目前非常 ...