node.js原生后台进阶(二)
上一章讲到怎么样用原生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原生后台进阶(二)的更多相关文章
- node.js原生后台进阶(一)
后台对于我们前端来说可能真的有点陌生,下面我来理清一下思绪吧. 一个基本的后台要求有如下功能: 1.与前端的数据交互 2.操作数据库(增删改查) 3.操作服务器文件(也大概是增删改查) 本次我们先讨论 ...
- Node.js原生及Express方法实现注册登录原理
由于本文只是实现其原理,所以没有使用数据库,只是在js里面模拟数据库,当然是种中还是需要用数据库的. 1.node.js原生方法 ①html页面,非常简单,没有一丝美化~我们叫它user.html & ...
- 用Node.js原生代码实现静态服务器
---恢复内容开始--- 后端中服务器类型有两种 1. web服务器[ 静态服务器 ] - 举例: wamp里面www目录 - 目的是为了展示页面内容 - 前端: nginx 2. 应用级服务器[ a ...
- 使用Node.js原生API写一个web服务器
Node.js是JavaScript基础上发展起来的语言,所以前端开发者应该天生就会一点.一般我们会用它来做CLI工具或者Web服务器,做Web服务器也有很多成熟的框架,比如Express和Koa.但 ...
- Node.js学习笔记(二):模块
模块是 Node.js 应用程序的基本组成部分,文件和模块是一一对应的.一个 Node.js 文件就是一个模块,这个文件可能是 JavaScript 代码.JSON 或者编译过的 C/C++ 扩展. ...
- 使用Node.js作为后台进行爬虫
看了一遍又一遍Node.js但是没过多久就又忘了,总想找点东西来练练手,就发现B站首页搜索框旁边的GIF图特别有意思,想着是不是可以写一个小Node.js项目把这些图全部扒下来,于是带着复习.预习与探 ...
- Node.js 蚕食计划(二)—— 使用 http 模块搭建 Web 服务器
Node.js 开发的目的就是为了用 JavaScript 编写 Web 服务器程序 这次就来介绍用 http 模块搭建服务器 一.项目构建 每个 Node 程序都可以看作一个模块,而每个模块都应该有 ...
- node.js学习笔记(二)——回调函数
Node.js 异步编程的直接体现就是回调. 那什么是回调呢?回调指的是将一个函数作为参数传递给另一个函数,并且通常在第一个函数完成后被调用.需要指明的是,回调函数不是由该函数的实现方直接调用,而是在 ...
- 编写Node.js原生扩展
Node.js是一个强大的平台,理想状态下一切都都可以用javascript写成.然而,你可能还会用到许多遗留的库和系统,这样的话使用c++编写Node.JS扩展会是一个不错的注意. 以下所有例子的源 ...
随机推荐
- 使用不同的方法计算TF-IDF值
摘要 这篇文章主要介绍了计算TF-IDF的不同方法实现,主要有三种方法: 用gensim库来计算tfidf值 用sklearn库来计算tfidf值 用python手动实现tfidf的计算 总结 之所以 ...
- Java类加载器学习笔记
今后一段时间会全面读一下<深入理解Java虚拟机> 在这里先记一下在网上看到的几篇介绍 类加载器 的文章,等读到虚拟机类加载机制再详细介绍. 超详细Java中的ClassLoader详解 ...
- 设计模式 笔记 命令模式 Command
//---------------------------15/04/25---------------------------- //Conmmand 命令模式----对象行为型模式 /* 1:意 ...
- stl源码剖析 详细学习笔记 算法(2)
//---------------------------15/03/29---------------------------- //****************************set相 ...
- Mabatis中#{}和${}的区别
动态 sql 是 mybatis 的主要特性之一,在 mapper 中定义的参数传到 xml 中之后,在查询之前 mybatis 会对其进行动态解析.mybatis 为我们提供了两种支持动态 sql ...
- ini_set的用法介绍
https://www.cnblogs.com/xieqian111/p/5367732.html
- 《Gogoing》Alpha版使用说明
前言: Gogoing是由我们山药蛋团队利用课余时间,基于安卓安卓系统开发完成.该软件针对于我们大学生没有赚钱能力,却又渴望外面的世界,该软件的核心理念的是“穷”游.为当代的大学生提供一个景点推荐或者 ...
- 重温jsp①
Jsp就是一个servlet servlet的缺点 不适合设置html响应体,需要response.Getwriter.print(); 优点:动态资源,可以编程. Jsp:在原有的html中加入了J ...
- 第二个Sprint冲刺第 八天(燃尽图)
因为今天停电了,所以我们也休息一天!
- Apache DBUtils框架 结果处理器
package com.itheima.dbutil; import java.util.List; import java.util.Map; import org.apache.commons.d ...