nodeJs是一个服务器框架,刚开始学习的时候认为nodeJs是一个Js框架,用来编写用户页面程序。但是学习一段时间之后,才发现原来它属于后台开发的,O(∩_∩)O哈哈~!
nodeJs 的性能测试工具:apache;
ab -n1000 -c http://localhost:2015/ -n 总请求数 -c 并发数 请求链接 这里例子的参数
总体参数
-n :总共的请求执行数,默认是1; -c: 并发数,默认是1; -t:测试所进行的总时间,秒为单位,默认50000s -p:POST时的数据文件 -w: 以HTML表的格式输出结果
学习一个框架当然要知道它自带的一些东西。node有一个类似于终端的解析器REPL。
node自带REPL(交互式解析器)
它的一些终端操作指令有:
-
ctrl + c - 退出当前终端。
-
ctrl + c 按下两次 - 退出 Node REPL。
-
ctrl + d - 退出 Node REPL.
-
向上/向下 键 - 查看输入的历史命令
-
tab 键 - 列出当前命令
-
.help - 列出使用命令
-
.break - 退出多行表达式
-
.clear - 退出多行表达式
-
.save filename - 保存当前的 Node REPL 会话到指定文件
-
.load filename - 载入当前 Node REPL 会话的文件内容
当然学习nodeJS需要了解它的数据处理流程。nodeJs的应用组成大体由三个部分组成:
1、引入require模块(相当于注入依赖),
2、创建服务器用来监听从客户端传过来的数据,
3、配置路由,找到相应的请求路径,处理数据,返回响应结果到客户端。
node中的URL
在页面中注入url:
const url = require("url");
url.parse(objUrl, '布尔值(默认为false)', '布尔值(默认为false)');注解:这个是企业应用中最常见的。具体以后在填坑。
当url.parse();只有一个参数时,如:
> url.parse('www://blog.csdn.net/qq_35023116/acticle/details/79194510')它的执行结果是:
> Url { ... protocol: 'www:', ... slashes: true, ... auth: null, ... host: 'blog.csdn.net', ... port: null, ... hostname: 'blog.csdn.net', ... hash: null, ... search: null, ... query: null, ... pathname: '/qq_35023116/acticle/details/79194510', ... path: '/qq_35023116/acticle/details/79194510', ... href: 'www://blog.csdn.net/qq_35023116/acticle/details/79194510' } ... > ...url.parse();两个参数时:
> url.parse('http://blog.csdn.net/qq_35023116/', true);结果是:
Url { protocol: 'http:', slashes: true, auth: null, host: 'blog.csdn.net', port: null, hostname: 'blog.csdn.net', hash: null, search: '', query: {}, pathname: '/qq_35023116/', path: '/qq_35023116/', href: 'http://blog.csdn.net/qq_35023116/' }
当设置第三个参数的时候:
> url.parse('http://blog.csdn.net/qq_35023116/', true, true);运行结果:
Url { protocol: 'http:', slashes: true, auth: null, host: 'blog.csdn.net', port: null, hostname: 'blog.csdn.net', hash: null, search: '', query: {}, pathname: '/qq_35023116/', path: '/qq_35023116/', href: 'http://blog.csdn.net/qq_35023116/' }
从上面可以看出,当设置了第二个参数为true的时候,query被解析为JSON对象;当设置第三个参数的时候,第一个//和第一个/之间的部分被解析为主机名。
url.format();注解:表面意思是格式化,就是将url的一些信息,组合成一个完整的网站地址。
url.resolve(from, to);注解:相当于拼接url地址。如url.resolve('http://blog.csdn.net/', '/qq_35023116');
返回的就是:http://blog.csdn.net/qq_35023116
node中的queryString;
在模块中注入queryString:
const queryString = require("queryString");
queryString.escape();
注解:escape可使传入的字符串进行编码
queryString.parse(str,separator,eq,options);
注解:parse这个方法是将一个字符串反序列化为一个对象。
参数:str指需要反序列化的字符串;
separator(可省)指用于分割str这个字符串的字符或字符串,默认值为"&";
eq(可省)指用于划分键和值的字符或字符串,默认值为"=";
options(可省)该参数是一个对象,里面可设置maxKeys和decodeURIComponent这两个属性:
maxKeys:传入一个number类型,指定解析键值对的最大值,默认值为1000,如果设置为0时,则取消解析的数量限制;
decodeURIComponent:传入一个function,用于对含有%的字符串进行解码,默认值为querystring.unescape。在官方API的例子中,使用gbkDecodeURIComponent这个方法会报错,显示gbkDecodeURIComponent is no defined,这是因为在使用这个gbkDecodeURIComponent这个方法之前需要先进行定义。在API中也写了Assuming gbkDecodeURIComponent function already exists...这句话的意思是”假设这个gbkDecodeURIComponent方法已经存在”。
例如,查询字符串'foo=bar&abc=xyz&abc=123'
被解析为:
{ foo:'bar', abc:['xyz', '123'] }
queryString.stringify();
注解:stringify这个方法是将一个对象序列化成一个字符串,与querystring.parse相对。
参数:obj指需要序列化的对象
separator(可省)用于连接键值对的字符或字符串,默认值为"&";
eq(可省)用于连接键和值的字符或字符串,默认值为"=";
options(可省)传入一个对象,该对象可设置encodeURIComponent这个属性:
encodeURIComponent:值的类型为function,可以将一个不安全的url字符串转换成百分比的形式,默认值为querystring.escape()。
queryString.unescape();
注解:unescape方法可将含有%的字符串进行解码。跟queryString.escape()相对。
刚才看到一个在源码中非常常见的函数util.inherits()。
util.inherits(constructor, superConstructor)是一个实现对象间原型继承 的函数。JavaScript 的面向对象特性是基于原型的,与常见的基于类的不同。JavaScript 没有 提供对象继承的语言级别特性,而是通过原型复制来实现的。
var util = require('util'); function Base() { this.name = 'base'; this.base = 1991; this.sayHello = function() { console.log('Hello ' + this.name); }; } Base.prototype.showName = function() { console.log(this.name); }; function Sub() { this.name = 'sub'; } util.inherits(Sub, Base); var objBase = new Base(); objBase.showName(); objBase.sayHello(); console.log(objBase); var objSub = new Sub(); objSub.showName(); //objSub.sayHello(); console.log(objSub);在上面的代码中,我们定义了一个基础对象Base 和一个继承自Base 的Sub,Base 有三个在构造函数 内定义的属性和一个原型中定义的函数,通过util.inherits 实现继承。运行结果如下所示:
base Hello base { name: 'base', base: 1991, sayHello: [Function] } sub { name: 'sub' }
注意:Sub 仅仅继承了Base 在原型中定义的函数,而构造函数内部创造的 base 属 性和 sayHello 函数都没有被 Sub 继承。
同时,在原型中定义的属性不会被console.log 作 为对象的属性输出。如果我们去掉 objSub.sayHello(); 这行的注释,将会看到: