nodejs
Posted 鹿晓晓
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了nodejs相关的知识,希望对你有一定的参考价值。
一:什么是nodejs?(node可以作为一个服务器)
官网:https://nodejs.org/en/
nodejs是一个基于chrome V8引擎的javascript运行时(可以解析和javascript语言,没有DOM和BOM)
*:nodejs不是一门语言,类似于浏览器,但是没有图形界面
nodejs使用高效、轻量级的事件驱动、非阻塞(异步的)的I/O模型
*:事件驱动
*:IO:输入与输出(异步)
nodejs的生态系统npm是目前最大的开源包管理系统
使用nodejs可以做什么?
网站开发、命令行应用程序
MEAN (mongodb express angularjs nginx(类似于apache的服务器))
WAMP(windows apache mysql php)
传统的web交互模型:
二:快速上手
1.环境安装:
(.msi格式的直接点击下一步安装)
https://nodejs.org/en/download/
打开cmd,输入 node -v 检查是否有node环境
2.cmd中输入node 进入node环境
cd:切换目录
node + 文件名:使用nodejs执行该文件
(实际是node.exe可执行程序读取了该文件,然后解析执行文件中的代码)
3.文件操作
//导入fs模块
var fs=require(\'fs\');
//文件的写入
//第一个参数:写入文件的路径(如果文件已经存在直接覆盖,如果不存在直接创建)
//第二个参数:指定要写入文件的数据
//注意:操作文件路径一定是相对路径或者绝对路径
// 如果是相对路径,最好加上./
//第三个参数:回调函数
//回调函数需要接受一个参数:err
//如果写入文件操作成功了,则err就是一个null
//如果写入文件操作失败了,则err就是一个异常对象
fs.writeFile(\'./data.txt\',\'hello world \',function(err){
if(err){
throw err;
}
console.log(\'写入文件成功了\');
});
注意:
写文件时目录名最好不要出现中文、不要出现空格、文件名也不要写中文
//导入文件模块 var fs=require(\'fs\'); //第一个参数:尧都区的文件名 //第二个参数:可选的,用来指定读取文件的编码格式(如:utf8),此处设置了编码,下面的data就不需要toString() //第三个参数:回调函数 // err: // 如果读取成功err就是null // 如果读取失败,err就是异常对象 // data:读取到的文件数据 fs.readFile(\'./data.json\',\'utf8\',function(err,data){//记得写编码格式 if(err){ throw err; }
//注意:此处获取的文件数据默认是二进制,要想获取要原始数据,需要将data.toString()
console.log(data);
})
4.服务器
//导入服务器模块 var http=require(\'http\') //1.创建服务器 var server=http.createServer() //2.给服务器实例对象server设置request请求事件处理函数
//request事件处理函数需要接受两个参数:
//Reques请求对象t:可以获取到客户端请求的一些数据,例如:url、请求方法
//Response响应对象:可以用来给客户端发送响应数据 server.on(\'request\',function(req,res){
console.log(req.url) console.log(\'有客户端请求进来了。。。。。\')
res.writeHead(200,{
\'Content-Type\':\'text/html;charset=utf8\'
})
//使用res响应对象的write方法向本次请求发送响应数据
//注意:可以多次使用write方法想客户端发送数据
//建议给客户端发送数据的时候,告诉客户端你发的数据是什么类型
res.write(\'hello\')
//发送完数据后要记得通知服务器响应完毕,即使只发送一个响应头也要记得end
res.end()
************************************************************
*//也可以直接把你要返回的数据写在end()里面,就可以不用写write()*
* res.end(\'<h1>hello</h1>\') *
************************************************************
===========================================================================
=//实现重定向
=//302状态码就表示重定向,浏览器看到302状态码后,会自动去响应报文头中找 Location属性=
=res.writeHead(302,{
= \'Location\':\'/\' //重新跳转到首页 =
=})
=========================================================================== }) //3.启动服务器,设置绑定一个端口号 //第一个参数:用来指定绑定的端口号。。。。 //第二个参数:可选的,指定绑定的ip地址, //第三个参数:回调函数 server.listen(\'3000\',function(){ console.log(\'server is running at port 3000\') console.log(\'please visit http://127.0.0.1:3000\') })
5.art-Template模板引擎
哪个项目中要使用该模板就进入根路径,执行npm install art-Template,npm会在当前目录下找node_modules目录,如果没有,直接创建,并将要下载的问价添加到该文件夹,如果有,直接下载到该文件夹。
//加载第三方包,不需要指定路径 var template=require(\'art-Template\') //1.调用template.compile函数,传入模板字符串 //调用该函数之后会得到一个render渲染函数 var render=template.compile(\'<h1>{{title}}</h1>\') //2.调用render渲染函数,传入一个数据对象 //返回解析替换后的字符串 render({ title:\'hello world\' })
//条件表达式 {{if admin}} <p>admin</p> {{else if code > 0}} <p>master</p> {{else}} <p>error!</p> {{/if}}
//数组和对象的遍历 {{each list as value index}} <li>{{index}} - {{value.user}}</li> {{/each}} 亦可以被简写: {{each list}} <li>{{$index}} - {{$value.user}}</li> {{/each}}
6.路径模块
var url=require(\'url\') //导入服务器模块 var http=require(\'http\') //导入处理post请求体的模块 var querystring=require(\'querystring\') //1.创建服务器 var server=http.createServer() //2.给服务器实例对象server设置request请求事件处理函数 server.on(\'request\',function(req,res){ //url模块中的parse方法可以将一个路径解析为一个对象 // 可以得到一个路径中的 请求路径部分、查询字符串部分、端口号 等信息 // 可以通过指定第二个参数为 true,自动将解析到的查询字符串解析为一个对象 var urlObj=url.parse(req.url,true) // 拿到请求路径中的查询字符串对象(get请求的获取方式) var queryObj = urlObj.query //获取post请求中的请求体 //表单post提交数据可能是很大的,所以post会把提交的数据进行分块传输 //在服务端也需要一块一块的接收 //通过监听req请求对象的data事件和end事件就可以接收 var data=\'\' req.on(\'data\',function(chunk){ //chunk接收到是二进制数据,和字符串拼接会自动调用toString()方法 //二进制数据有一个length属性,获取到的就是二进制数据的字节 data+=chunk }) req.on(\'end\',function(){ //通过使用内置模块去二院string的parse将一个查询字符串转换为一个对象 var body=querystring.parse(data) }) // // 只拿到请求路径中的路径部分(不包含查询字符串) var pathname = urlObj.pathname console.log(\'有客户端请求进来了。。。。。\') }) //3.启动服务器,设置绑定一个端口号 server.listen(\'3000\',function(){ console.log(\'server is running at port 3000\') console.log(\'please visit http://127.0.0.1:3000\') })
三:nodejs中的模块化
//一个文件就是一个模块 //每个模块就是一个私有的作用域 //默认模块内部定义的所有成员都只能在模块内部使用 //require函数用来加载一个模块 // 1.从头到尾执行模块中的代码 // 2.可以得到模块内部的通信接口对象:module.exports var add=require(\'./add\') //node中完全就是模块化的编程方式 //每个js文件就是一个模块 //每个模块就是一个私有作用域 //在每个模块内部还提供了一个通信接口对象:module.eports接口对象 //模块与模块之间可以通过require函数进行加载执行,并得到被加载模块内部的接口对象 //模块与模块之间还可以互相依赖 //module.exports用来向外暴露该模块内部的数据 //在每个模块内部还提供了一个成员:eports接口对象 //exports就是module.exports接口对象的一个引用 //exports===module.exports //使用require注意事项: // 1.加载相对路径文件模块一定要以./或者../开头 // 2.加载模块文件时后缀名可以省略,node中推荐省略后缀名 //如果一个模块想要向外暴露一个单独的接口成员 //例如:只暴露一个函数、字符串、数字、数组等成员 //就需要通过module.exports接口对象赋值即可 module.exports=function(){ return x+y; } //注意:每个模块内部最终向外暴露的是module.exports //exports只是module.exports接口对象的一个引用 //所以一旦给exports接口对象赋值,exports和 module.exports就失去引用关系
核心模块(node内置)
1.核心模块就是node内置的模块,需要通过唯一的标识名来进行获取。
2.每一个核心模块基本上都只是暴露了一个对象,里面包含了一些方法供我们使用
3.一般在加载核心模块的时候,变量的起名最好就和核心模块的标识名同名即可
eg:`var fs=require(\'fs\')`
4.核心模块本质上也是文件模块
核心模块已经被编译到了node的可执行程序,一般看不到
可以通过查看node的源代码看到核心模块文件
核心模块也是基于commonjs模块规范
--------------------------------------------------------------------------------------------------------------------------------------
-----------CommonJS规范加载模块是同步的,也就是说,只有加载完成,才能执行后面的操作。---------------------------------
-----------AMD规范则是非同步加载模块,允许指定回调函数。
-----------由于Node.js主要用于服务器编程,模块文件一般都已经存在于本地硬盘,所以加载起来比较快,-----------------------
-----------不用考虑非同步加载的方式,所以CommonJS规范比较适用。----------------------------------------------------------
-----------但是,如果是浏览器环境,要从服务器端加载模块,这时就必须采用非同步模式,因此浏览器端一般采用AMD规范。---
--------------------------------------------------------------------------------------------------------------------------------------
每个模块都提供了单一的功能,以下是常用的核心模块
| 模块名称 | 模块作用 |
| ---------------|----------------- |
| fs | 文件操作 |
| http | http服务 |
| path | 路径处理 |
| url | 处理url路径 |
| querystring | 处理查询字符串 |
| os | 操作系统相关 |
| net | socket网络编程 |
| util | 工具函数 |
| | |
模块的加载流程:
*:优先从缓存加载
*:在一个模块系统中,模块第一次被加载的时候会执行模块中的代码,通过把该模块的接口对象缓存起来。
*:如果多次加载该模块,不会执行该模块中的代码了,直接从缓存中将该模块的接口对象取出来。
*:加载模块得到的是内部接口对象的复制
*:一旦第一次加载过后,拿到的是接口数据的备份,如果模块内部的成员被修改了,是不会影响到外部的使用。
5.
//读取文件的时候 //如果文件是以/ 开头的,则直接去当前文件所属盘符根目录去找 //读取文件的时候相对路径是以相对于执行node命令的时候所处的目录的 var path=require(\'path\') //拼接路径 //join方法支持拼接多个路径,也支持拼接上一级路径 //path.join(\'/a/b/c\',\'./d\',\'../e\') path.join(\'__dirname\',\'index.js\')
6.momentjs插件
//转换中文格式
moment.local(\'zh-cn\')
moment(\'20120311\',\'YYYYMMDD\').fromNow();//5 years age var time=new Date().getTime();//获取当前时间 moment(time).startOf(\'second\').fromNew();//x minutes age //获取当前时间并且格式化 moment().format(\'YYYY-MM-DD hh-mm-ss\')//2017-03-11 10:21:16
四:node中的javascript
ECMAScript
console
setInterval()
setTimeout()
clearInterval(id)
clearTimeout(id)
clearImmediate()
setImmediate()
__dirname
__filename
global
process
require()
exports
module
五:MongoDB数据库
- 官网:https://www.mongodb.com/ - 菜鸟教程:http://www.runoob.com/mongodb/mongodb-tutorial.html - MongoDB 是一个面向文档存储(JSON)的 **非关系型** 数据库,可以用来存储网站应用程序的数据 + MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成 + MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组 + **非关系型** 后面给大家介绍 MySQL 数据库就会了解各大数据库的区别了 - MongoDB 数据库是跨平台的,可以在 Linux、Mac OSX、Windows 等平台使用 - MongoDB 诞生于 2009 年,由 10gen 团队创建
安装MongoDB
下载地址:https://www.mongodb.com/download-center + 根据自己的操作系统下载对应的数据库版本 - 在 Windows 平台安装 MongoDB 数据库环境 + 教程:http://www.runoob.com/mongodb/mongodb-window-install.html + 注意:所谓的 MongoDB 数据库环境其实是个服务,没有图形界面 - 验证是否安装成功 + 在终端中输入 `mongod --version` 命令进行查看 + 如果能看到安装好的 MongoDB 数据库版本号,说明安装成功 **注意:** 如果安装成功,但是执行 `mongod --version` 命令提示不是内部命令的错误, 这个时候将 MongoDB 的安装目录中的 bin 目录配置到环境变量,然后再次尝试。
启动和关闭 MongoDB 数据库服务程序 > Tips:以下操作请确保你执行 `mongod --version` 能看到安装的服务版本号 `mongod` 命令用来启动 MongoDB 数据库,但是如果你第一次执行该命令,你会发现报错了。 这是因为 MongoDB 服务默认使用 `C:/data/db` 目录作为自己的数据存储目录, 这个时候如果没有该目录,则自己手动创建 `C:/data/db` 该目录,然后再次使用 `mongod` 启动数据库服务。 如果你想要使用别的数据存储目录,则可以通过 `mongod --dbpath=数据存储路径` 的形式启动 MongoDB 服务。 启动成功之后,你会发现控制台输出一大堆字符,并且没有退出,那这个时候表示 MongoDB 服务启动成功, 然后就可以把这个控制台最小化了,只要不关闭该窗口,MongoDB 服务实例就会一直运行。 如果想要关闭 MongoDB 服务,则可以在运行 MongoDB 服务的控制台中通过 `Ctrl + C` 关闭服务。 上述都是针对 64 位操作系统的操作步骤,如果是 32 位操作系统,则可以使用下面的方式启动 MongoDB 数据服务: ```bash $ mongod --dbpath 数据存储路径 --journal --storageEngine=mmapv1 ```
//打开终端,输入\'mongod\'回车 //\'mongod\'命令用来启动MongoDB数据服务 //MongoDB服务默认将C:/data/db目录作为数据目录 //所以需要先在C盘根目录下新建一个目录:C:/data/db //当执行mongod命令的时候,就会默认使用C:/data/db作为目录存储数据 //如果你不想使用C:/data/db //mongod --dbpath=路径 --journal --storageEngine=mmapv1 //一个计算机上只能安装一个mongodb应用服务实例 //一个mongodb服务实力上可以创建多个数据库 //一个数据库中可以有多个集合,一个集合中存储的就是文档(其实就是json对象)
mongodb启动
//打开终端输入mongod //再打开一个终端输入mongo //注意:是两个终端,不可以关闭其中任意一个 //mongodb默认连接到127.0.0.1:27017
操作数据库
show dbs //查看mongodb服务中有哪些数据库 use + \'数据库名字\'//切换数据库 //如果该数据库不存在,会先进入该数据库 //只有当你真正在该数据库中存储了一个集合之后,才会真正的创建数据库 db //查看当前所属的数据库 db.dropDatabase()//删除数据库(要先进入该数据库) db.collection.drop()//删除集合
show collection//进入数据库查看所有的集合
//增加数据 db.集合名.insert({name:jack,age:10})//插入数据
//查询数据 db.集合名.find()//查询指定集合的所有数据 db.集合名.find().pretty()//格式化的形式读取集合数据
//更新数据 db.集合名.update({更新条件},{要更新的数据对象})//默认更新所有,其实就是替换了 db.集合名.update({更新条件},{$set:{要更新的字段名:要更新的字段值}})//更新指定字段 //如果被更新的字段已经存在则直接更新,如果不存在,则直接向被匹配的文档中增加该字段 db.集合名.update({更新条件},{$set:{要更新的字段名:要更新的字段值}},{multi:true})//替换符合条件的多个 db.集合名.save({})//插入数据 db.集合名.save({_id:ObjectId(\'\')},{key:value})//整体替换
//删除数据 db.集合名.remove({匹配条件})//删除指定数据(默认删除匹配到的所有数据) db.集合名.remove({匹配条件},{justOne:true})//只删除符合条件的第一个
nodejs操作mongodb
//node中操作mongodb npm install mongodb --save//安装mongodb模块 var mongodb=require(\'mongodb\') var MongoClient=mongodb.MongoClient() MongoClient.connect(\'mongodb://localhost:27017/数据库名\',function(err,db){ if(err){ throw new Error(\'连接失败\') } //添加数据 db.collection(\'集合名\') .insertMany([ {key:value} ],function(err,result){ if(err){ throw new Error(\'添加失败\') } }) //查询所有 db.collection() .find({})//查询指定,则只需传入查询条件 .toArray(function(err,docs){ if(err){ throw new Error(\'查询失败\') } }) //操作完数据库后,要关闭连接 db.close() })
六:express框架
//初始化项目结构 npm init //在当前文件的根目录初始化一个package.json文件 //(项目说明文件) name:项目名称 version:版本 description:项目描述 main:入口文件 scripts:{ \'test\':\'\', \'start\':\'node app.js\' } *:当你在终端输入npm start的时候 *:npm会自动找到package.json中的scripts中的start属性 *:然后帮你执行start属性配置好的命令 dependencies:{} 项目的依赖项(第三方包) *:npm install //会自动找到package.json中的dependencies依次安装依赖包
express基本使用
//导入express模块 var express=require(\'express\') //1.调用express()得到一个app应用实例 //express()就相当于http.createServer() //app就相当于原来的server var app=express() //在express中,render方法是需要单独来配置 //对于express来说需要单独配置要使用的模板引擎 //express 框架本身很灵活,很多功能需要单独配置才可以使用 //相对于 express 来说,配置这些东西其实就是插件 // 只要通过下面的配置,在 express 中就可以正常的使用 render 方法了 // 一定要记得使用 render 的时候,加上后缀名 app.render(\'\', function(err, html){ // ... }); //2.给app应用实例挂载路由 app.get(\'/\',function(req,res){ res.end(\'hello world\') }) //3.绑定端口,启动服务器 app.listen(\'3000\',function(){ console.log(\'server is running.......\') })
七:nunjucks插件
nunjuck基本配置使用:
//nunjucks模板引擎----------nodejs中超牛的模板引擎
npm install nunjucks --save
var express = require(\'express\') var nunjucks = require(\'nunjucks\')
var app = express() // 在 express 中,render方法需要单独配置的 // 对于express来说,需要单独配置使用的模板引擎 // 相对于express来说,配置这些东西其实就是插件 //只要通过下面的配置,在express中就可以正常使用render方法了
nunjucks.configure(\'views\',{
express:app
}) app.get(\'/\',function(req,res){
res.render(\'index.html\')
}) app.listen(3000, function () { console.log(\'running...\') })
nunjucks模板引擎处理静态资源:
var express = require(\'express\') var nunjucks = require(\'nunjucks\') var path = require(\'path\') var router = require(\'./router\') var bodyParser = require(\'body-parser\') var app = express() // 在 express 中暴露公共资源 // 在 express ,也是通过配置的形式提供对静态资源的处理 // 第一个参数用来配置静态资源的前缀路径 // 第二个参数用来指定该模糊路径查找的磁盘路径 // 第一个参数是可选参数,可以不指定 // 如果不指定第一个参数,则请求的时候,就不要加任何前缀 // ,直接请求该目录中的资源路径就可以了 // 例如你要请求 node_modules/bootstrap/dist/css/bootstrap.css // 则请求的时候,不要加 /node_modules 前缀,直接 /bootstrap/dist/css/bootstrap.css 就可以了 app.use(\'/node_modules\',express.static(path.join(__dirname, \'node_modules\'))) app.use(\'/public\', express.static(path.join(__dirname, \'public\'))) //配置nunjucks模板引擎 // noCache 用来指定缓存配置,默认是 false var env = nunjucks.configure(config.viewPath, { noCache: true }) env.express(app) // 配置解析表单 post 提交数据的插件 // 该插件的名字叫:body-parser // 可以专门用来和 express 结合使用,解析请求体中表单 post 提交的数据 // 只要使用了下面的配置,该插件会自动帮你把表单 post 请求体数据解析成一个对象, // 然后挂载给 req 请求对象的 body 属性 // 也就是说,在后面的所有的处理函数中,如果想要拿到表单 post 请求体数据, // 直接通过 req.body 来拿就可以了 app.use(bodyParser.urlencoded({ extended: false })) app.use(bodyParser.json()) // 2. 给 app 应用实例挂载路由 app.use(router) // 3. 绑定端口,启动服务器 app.listen(3000, function () { console.log(\'running...\') })
八、改完代码自动重启服务器
通过使用第三方命令行工具 `nodemon` 来解决改完代码重启服务器的问题 `nodemon` 是一个基于 Node 开发的一个第三方命令行工具,要想使用,在终端中通过: ```bash $ npm install --global nodemon ``` 安装完毕之后,把原来使用 `node app.js` 替换成 `nodemon app.js`, 这样的话就可以实现服务器端代码修改,直接自动重启服务器。
注意:全局命令行工具一次安装,永久使用,以后再使用,就不用再次安装了。
九、cnpm
通过 cnpm 改变镜像源地址的方式解决 npm 被墙问题 - http://npm.taobao.org/ 淘宝 NPM 镜像,这是一个完整 npmjs.org 镜像,你可以用此代替官方版本(只读),同步频率目前为 10分钟 一次以保证尽量与官方服务同步。 只需要在下载包的时候,加上 `--registry=https://registry.npm.taobao.org`,那这样的话就会通过 淘宝的 `cnpm` 去下载,例如: ```bash $ npm install 包名 --registry=https://registry.npm.taobao.org ``` 这样话虽然可以解决,但是每次下载包的时候,还要自己手动加上这个参数,有一个更好的: ```bash $ npm config set registry=https://registry.npm.taobao.org ``` 该命令表示设置 npm 下载的镜像源地址为: `https://registry.npm.taobao.org`, 只要做了执行了该命令,那以后所有的 `install` 都会使用该地址。 如果想要删除该配置,使用下面的命令: ```bash $ npm config delete registry ``` 还可以通过下面的命令查看当前 npm 的配置列表: ```bash $ npm config list ```
十、requirejs基本使用
以上是关于nodejs的主要内容,如果未能解决你的问题,请参考以下文章
javascript 用于在节点#nodejs #javascript内设置react app的代码片段