热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

快速入门nodejs学习

nodejs学习简介nodejs是一个事件驱动IO服务端的JavaScript环境,没有DOM,浏览器之类的东西。Chrome的V8引擎是用C++写的,执行JS速度快。powers




nodejs学习


简介


  • nodejs是一个事件驱动I/O服务端的Javascript环境,没有DOM,浏览器之类的东西。
  • Chrome的V8引擎是用C++写的,执行JS速度快。
  • powershell是功能更强的cmd。

创建服务

创建一个http服务由以下3个部分构成:


  • 引入模块,require,把这个模块用一个变量接收。

    var xx = require(“http”);

  • 创建服务器

  • 处理请求与响应

    //创建一个服务
    //引入一个模块,把这个模块保存在 _httpv变量当中
    var _httpv = require("http");
    // console.log(_httpv.createServer)
    _httpv.createServer(function(request,response){
    //http头部的信息
    //状态码200
    //内容的类型:text/plain(纯文本), text/html(html形式)..., xml
    response.writeHead(200,{'Content-Type':'text/html'});
    //向客户端发送数据
    response.end("hello nodejs");
    }).listen(8080);
    //控制台打印信息
    console.log("8080已经创建!")


本质

创建各种服务,通过各种接口,提供各种数据。


基本概念


异步编程

异步编程的直接体现:异步回调的直接体现:异步回调

1.开发语言是js,js本身就是事件驱动的,是异步的;

2.因为是js的,所以是单线程的,现在是多线程的。

通过异步来处理大并发:

阻塞的例子:.readFileSync(文件名)是同步读取文件

// 通过异步来处理大并发(一个阻塞的例子)
//在nodejs中操作文件使用的是fs模块
var _fs = require("fs");
// console.log(_fs.readSync)
//.readFileSync是同步读取文件
var _data = _fs.readFileSync('New Collection.postman_collection.json');
//直接输出会是个二进制的流,此时可以采用toString方法
// console.log(_data);
console.log(_data.toString());
console.log('js已经执行结束');
/*
这种操作在本质上已经形成了阻塞
*/

非阻塞的例子:.readFile()基于回调的异步读取文件

//基于回调的非阻塞的文件读取
var _fs = require('fs');
//第一个参数是要读取的文件名
//第二个参数是处理读取到的文件的内容的回调函数
_fs.readFile('New Collection.postman_collection.json',function(err,_data)){
if(err) return err;
console.log(_data.toString());
};
console.log("----------");
console.log("js已经执行结束!");
/*
我们不需要等待文件读取完成,可以在读取文件的时候同时去执行下面的代码,提高了js的性能。
*/

回调的例子:回调的函数一般是作为最后一个形参出现。

实际工作中,最具体的应用就是jq的$.ajax()。




nodejs的事件(一)


  • nodejs是一个单进程单线程的应用程序,由于V8引擎提供了异步执行回调的接口,通过这些接口处理大的并发请求,性能很高。

  • 基本上nodejs所有的事件机制,都是基于设计模式中的“观察者模式”来实现的。

  • nodejs使用事件驱动的模型:每当接收到一个请求,就把它关掉进行处理,当这个请求完成,就把它放到处理队列当中,最后把结果返回给用户。

  • 由于nodejs的服务一直都是处理接收请求,但不等待任何的读写操作,所以性能很高,这也叫“非阻塞式的I/O或是事件驱动I/O"。

    nodejs的事件是使用 events 模块(require(“events”)),通过实例化( var event = new xx.EventEmitter)它里面的 EventEmitter 类来绑定和监听事件。

  • 绑定事件:event.on(…)

  • 监听事件:event.emit(…)

    node中的js,依然还是那个js,依然是从上到下一行一行的读取的解释型的脚本语言。编写时依然要注意顺序。

    /*
    nodejs 事件
    */
    var _events = require("events");
    //EventEmitter的一个实例
    var _EventEmitter = new _events.EventEmitter();
    //这里的事件名,完全不同于浏览器的各种事件,这里完全就只是一个标识,它其实是绑定了一个回调函数。
    _EventEmitter.on("xx123",function(){
    console.log("xx123事件已经被触发");
    //事件的嵌套
    _EventEmitter.emit("xx456");
    });
    _EventEmitter.on("xx456",xx456fn);
    function xx456fn(){
    console.log("xx456事件已经被触发");
    }
    //触发一个事件
    _EventEmitter.emit("xx123");
    console.log(_EventEmitter);


nodejs的事件(二)


  • nodejs里面所有异步的io操作,都会在完成时,发送一个事件到事件队列。
  • events这个模块只有一个对象events.EventEmitter,它的核心就是“事件触发与监听功能的封装”。

//第一个nodejs的事件的例子
var _EventEmitter = require("events").EventEmitter;
var _event = new _EventEmitter();
_event.on("timeout",function(){
console.log("timeout 事件被触发!");
})
setTimeout(function(){
_event.emit("timeout");
},2000)
console.log(_event);

  • EventEmitter,它的每个事件都是由:

    1.事件名,是一个字符串

    2.若干个参数

可以在一个实例上,通过on绑定多个事件,然后通过同一个.emit()方法触发并传参。如下实例:

//可以在一个实例上,通过on绑定多个事件,然后通过同一个.emit()方法触发并传参
var _EventEmitter = require("events").EventEmitter;
var _event = new _EventEmitter();
_event.on("xx1",function(arg1,arg2){
console.log("xx11111",arg1);
})
_event.on("xx1",function(arg1,arg2){
console.log("xx22222",arg2);
})
_event.emit("xx1","这是1111","这是2222");

Buffer(缓冲区/缓存)


  • nodejs的开发语言就是js,Javascript语言自身只有字符串数据类型,没有二进制数据类型。
  • nodejs有时会操作一些文件,或者说是tcp流之类的东西,那就必须操作二进制数据。
  • 在nodejs中,有一个buffer类,它用来创建一个专门存放二进制数据的缓存区。
  • buffer类是随nodejs的核心一起安装的,直接引入即可,这些原始数据是存储在buffer类的实例里,一个buffer类相当于是一个整数的数组,它相当于是划出了一块自己的内存空间。
  • buffer类的实例用于表示 编码字符 的序列,它支持utf-8,base64,ascii等。

1.创建一个Buffer类:

Buffer.alloc,它是返回一个指定大小的Buffer实例。

//创建一个长度为10,并且用0填充的buffer
const buf1 = Buffer.alloc(10);

2..write()向buffer实例中写入内容:

3..toString(),从缓冲区中读取数据。下面是其中的参数:


  • 默认编码是utf8
  • start,开始位置
  • end,结束位置

//创建一个长度为10,并且用0填充的bufferconst buf1 = Buffer.alloc(256);let text = buf1.write("我是秃头小框");console.log(buf1);console.log("写入的字节数:"+text);console.log(buf1.toString());console.log(buf1.toString('utf8',0,3));

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mMGOonTk-1622692398527)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20210527151818913.png)]

例子:

//批量输出26个字母const buf = Buffer.alloc(26);for(var i=0;i<26;i++){ buf[i] = 97 + i;}console.log(buf);console.log(buf.toString());console.log(buf.toString("ascii"));

4.将Buffer转换为JSON对象:


  • buf.toJSON(),它的返回值是一个json对象。

  • 调用Buffer.from(),它是返回一个被array的值,初始化之后的新的Buffer实例。

  • array之中的元素只能是数字,否则会被0覆盖。

//0x加数字表示是16进制的数字const buf1 = Buffer.from([0x1,0x2,0x3]);console.log(buf1);

5.JSON.stringify(),用于将Javascript值(对象/数组)转化为一个JSON字符串。

//0x加数字表示是16进制的数字const buf1 = Buffer.from([0x1,0x2,0x3]);const _json = JSON.stringify(buf1);console.log(buf1);console.log(_json);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Gw8YWj7R-1622692398534)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\image-20210527154913845.png)]

6.JSON.parse()是将json字符串,转为json对象。

//0x加数字表示是16进制的数字const buf1 = Buffer.from([0x1,0x2,0x3]);const _json = JSON.stringify(buf1);console.log(buf1);console.log(typeof _json);//字符串类型console.log(typeof JSON.parse(_json));//对象类型console.log(typeof JSON.parse(_json).data);

Stream流


  • Stream流(简单理解就是一个在线读取的资源),是一个抽象的接口,在nodejs当中,很多方法、对象。它们都实现了这个接口。

    例如:之前创建一个服务,向服务器发起一个请求,request对象,它其实就是个Stream。

  • 在nodejs当中,Stream有四种流类型:


    • Readable —可读操作
    • Writeable —可写操作
    • Duple—可读可写操作
    • Transform —操作被写入数据,然后读出结果
  • 所有的Stream对象,都是EventEmitter的实例,常用的事件:


    • data 当有数据可读取时触发
    • end 没有更多的数据可读取时触发
    • error 在接收和写入过程中,发生错误时触发
    • finish 所有的数据读取完成时触发

虽然是从流中去读取文件,但是依然是在操作文件,所有还是要用到nodejs当中的fs模块。


读取流示例

var fs = require('fs');var data = '';//创建一个可读流var readStream = fs.createReadStream("Words.txt");//设置可读流的编码格式,utf8readStream.setEncoding('utf8');//处理流的事件,data,error,endreadStream.on('data',function(_d){ data += _d;});readStream.on('end',function(){ console.log(data);});console.log("读取完毕!");

写入流示例

var fs = require('fs');var data = '我是秃头小框,我喜欢这个世界!';//创建一个可以写入的流var writeStream = fs.createWriteStream("writedemo.txt");//设置编码writeStream.write(data,'utf8');//标记文件末尾writeStream.end();writeStream.on('finish',function(){ console.log("写入完成!");});console.log("执行完成了!");

  • nodejs中的管道流,提供了一个从输出流到输入流的机制(就像水龙头一样,从一个地方流入到了另一个地方),就是从一个流当中获取数据,并传递到另一个流当中,主要用到了,.pipe()方法。

管道流示例

var fs = require('fs');//创建一个可读流,createReadStreamvar readStream = fs.createReadStream("writedemo.txt");//创建一个可以写入的流var writeStream = fs.createWriteStream("pipedemo.txt");//管道流操作readStream.pipe(writeStream);console.log("执行完毕!");

  • 链式流就是从一个输出流中读取数据,创建了多个流来操作这个输出流的数据的机制。一般用来操作管道流,常见的例子就是压缩和解压缩(zlib)。

链式流示例

压缩:

var fs = require('fs');var zlib = require('zlib');//压缩文件fs.createReadStream("writedemo.txt") .pipe(zlib.createGzip()) .pipe(fs.createWriteStream("writedemo.txt.gz"));console.log("压缩完了!");

解压缩:

var fs = require('fs');var zlib = require('zlib');//解压缩文件fs.createReadStream("writedemo.txt.gz") .pipe(zlib.createGunzip()) .pipe(fs.createWriteStream("Gunzipwritedemo.txt"));console.log("解压缩完了!");

模块系统


  • 模块是nodejs应用程序的基本组成部分。

  • 文件和模块是一一对应的,一个是nodejs的文件,就是一个模块。

  • nodejs提供了两个对象:


    • exports—它是模块公开的接口
    • require—用来获取外部的模块的接口
  • 创建模块的两种方式


    • 只公开一个方法(一般公开的方法名和它所在的模块是同名的):exports.方法名 = function(){ … }
    • 把整个模块都全部公开出来:moudle.exports = function(){ … }

get请求


  • 获得get请求的内容,它的内容是在URL的?号之后的部分(例如:?a=1&b=2&c=3):


    • util(nodejs的工具对象,有许多许多的方法)
    • util.inspect,用来把对象转换为字符串
    • url,是nodejs的url模块
    • url.parse,解析url请求之类的东西

    js//get请求var _http = require('http');var _util = require('util');var _url = require('url');_http.createServer(function(req,res){ res.writeHead(200,{ 'Content-Type':'text/plain;charset=utf-8' }); var _param = _url.parse(req.url,true).query; console.log(_param); // res.end('xx123'); //end方法只能向页面发送字符串 //res.end(_url.parse(req._url));error:_url.parse(req._url)是一个对象 // res.end(_util.inspect(_url.parse(req._url))); res.write("姓名:"+_param.name); res.write("\n"); res.write("年龄:"+_param.age); res.end();}).listen(5642);console.log('5642端口服务已经打开');


post请求


  • 要用到querystring,用来解析url的,querystring.parse(),用于将一个字符串转换为对象。

    //post请求var _http = require('http');var querystring = require('querystring');var _formHtml = '' + '姓名:
    '+ '年龄:
    '+ '' + '';_http.createServer(function(req,res){ var body = ''; req.on('data',function(_d){ body += _d; }); req.on('end',function(){ body = querystring.parse(body); res.writeHead(200,{ 'Content-Type':'text/html;charset=utf-8' }); if(body.name){ res.write('姓名:' + body.name); res.write('
    '); res.write('年龄:' + body.age); } else{ res.write(_formHtml); } res.end(); });}).listen(5642);console.log('5642端口服务已经打开');


express框架


  • 一个简洁的nodejs web应用框架,它提供一些功能,可以帮助你快速地搭建一个完整的网站。
  • 核心特性:
    • 可以使用中间件来响应http请求
    • 可以设置一些简单的路由:(手动)
  • 安装 Express,npm install express --save(–save意思是安装在你的开发目录,而不是全局安装。)

使用express创建一个服务

var express = require('express');// console.log(express);var app = express();//'/',就是根路径app.get('/',function(req,res){ res.send('第一个express例子,创建一个服务');});app.listen(5472,function(){ console.log("5472已经启动");});

express路由


  • 简单的路由,就是一个最简单的spa单页应用

express创建路由

var express = require('express');// console.log(express);var app = express();//'/',就是根路径app.get('/',function(req,res){ res.send('1
a页面
b页面');});app.get('/a',function(req,res){ res.send('2
a1页面');});app.get('/a/a1',function(req,res){ res.send('2.1
回到首页');});app.get('/b',function(req,res){ res.send('1.1
b1页面');});app.get('/b/b1',function(req,res){ res.send('1.2回到首页');});app.listen(5472,function(){ console.log("5472已经启动");});

静态目录


  • Express有内置的中间件的设置,可以用来设置静态目录,express.static(),可以让我们通过http的方式,来访问静态文件。
  • 它的效果和我们把文件放在phpstudy服务器上面的效果是一样的。

var express = require('express');var app = express();//设置静态目录app.use(express.static('staticDev'));app.listen(5472,function(){ console.log('5472,静态目录,已经启动');});


推荐阅读
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 本文介绍了使用AJAX的POST请求实现数据修改功能的方法。通过ajax-post技术,可以实现在输入某个id后,通过ajax技术调用post.jsp修改具有该id记录的姓名的值。文章还提到了AJAX的概念和作用,以及使用async参数和open()方法的注意事项。同时强调了不推荐使用async=false的情况,并解释了JavaScript等待服务器响应的机制。 ... [详细]
  • 在重复造轮子的情况下用ProxyServlet反向代理来减少工作量
    像不少公司内部不同团队都会自己研发自己工具产品,当各个产品逐渐成熟,到达了一定的发展瓶颈,同时每个产品都有着自己的入口,用户 ... [详细]
  • SpringMVC接收请求参数的方式总结
    本文总结了在SpringMVC开发中处理控制器参数的各种方式,包括处理使用@RequestParam注解的参数、MultipartFile类型参数和Simple类型参数的RequestParamMethodArgumentResolver,处理@RequestBody注解的参数的RequestResponseBodyMethodProcessor,以及PathVariableMapMethodArgumentResol等子类。 ... [详细]
  • 本文介绍了绕过WAF的XSS检测机制的方法,包括确定payload结构、测试和混淆。同时提出了一种构建XSS payload的方法,该payload与安全机制使用的正则表达式不匹配。通过清理用户输入、转义输出、使用文档对象模型(DOM)接收器和源、实施适当的跨域资源共享(CORS)策略和其他安全策略,可以有效阻止XSS漏洞。但是,WAF或自定义过滤器仍然被广泛使用来增加安全性。本文的方法可以绕过这种安全机制,构建与正则表达式不匹配的XSS payload。 ... [详细]
  • 如何实现织梦DedeCms全站伪静态
    本文介绍了如何通过修改织梦DedeCms源代码来实现全站伪静态,以提高管理和SEO效果。全站伪静态可以避免重复URL的问题,同时通过使用mod_rewrite伪静态模块和.htaccess正则表达式,可以更好地适应搜索引擎的需求。文章还提到了一些相关的技术和工具,如Ubuntu、qt编程、tomcat端口、爬虫、php request根目录等。 ... [详细]
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • Centos7.6安装Gitlab教程及注意事项
    本文介绍了在Centos7.6系统下安装Gitlab的详细教程,并提供了一些注意事项。教程包括查看系统版本、安装必要的软件包、配置防火墙等步骤。同时,还强调了使用阿里云服务器时的特殊配置需求,以及建议至少4GB的可用RAM来运行GitLab。 ... [详细]
  • t-io 2.0.0发布-法网天眼第一版的回顾和更新说明
    本文回顾了t-io 1.x版本的工程结构和性能数据,并介绍了t-io在码云上的成绩和用户反馈。同时,还提到了@openSeLi同学发布的t-io 30W长连接并发压力测试报告。最后,详细介绍了t-io 2.0.0版本的更新内容,包括更简洁的使用方式和内置的httpsession功能。 ... [详细]
  • http:my.oschina.netleejun2005blog136820刚看到群里又有同学在说HTTP协议下的Get请求参数长度是有大小限制的,最大不能超过XX ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • position属性absolute与relative的区别和用法详解
    本文详细解读了CSS中的position属性absolute和relative的区别和用法。通过解释绝对定位和相对定位的含义,以及配合TOP、RIGHT、BOTTOM、LEFT进行定位的方式,说明了它们的特性和能够实现的效果。同时指出了在网页居中时使用Absolute可能会出错的原因,即以浏览器左上角为原始点进行定位,不会随着分辨率的变化而变化位置。最后总结了一些使用这两个属性的技巧。 ... [详细]
  • 本文介绍了Sencha Touch的学习使用心得,主要包括搭建项目框架的过程。作者强调了使用MVC模式的重要性,并提供了一个干净的引用示例。文章还介绍了Index.html页面的作用,以及如何通过链接样式表来改变全局风格。 ... [详细]
  • JavaScript和HTML之间的交互是经由过程事宜完成的。事宜:文档或浏览器窗口中发作的一些特定的交互霎时。能够运用侦听器(或处置惩罚递次来预订事宜),以便事宜发作时实行相应的 ... [详细]
  • Android实战——jsoup实现网络爬虫,糗事百科项目的起步
    本文介绍了Android实战中使用jsoup实现网络爬虫的方法,以糗事百科项目为例。对于初学者来说,数据源的缺乏是做项目的最大烦恼之一。本文讲述了如何使用网络爬虫获取数据,并以糗事百科作为练手项目。同时,提到了使用jsoup需要结合前端基础知识,以及如果学过JS的话可以更轻松地使用该框架。 ... [详细]
author-avatar
Smile--麦芽
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有