Node.js 基本介绍
Node.js是什么
Node.js ® 是一个基于Chrome V8引擎的JavaScript 运行环境
(Node.js ® is a JavaScript runtime built on Chrome’s V8 JavaScript engine.)
名词解释
chrome V8引擎:在chrome浏览器用来解析和执行js代码的工具;
运行时:理解为一个容器,用来运行代码的环境;
Node.js是:一个采用chrome浏览器V8引擎来跑JS代码的环境。
浏览器是javascript的前端运行环境;
Node.js是javascript的后端运行环境;
前端运行环境能给我们带来什么能力?
展示和操作页面上的dom元素的能力
后端运行环境能给我们带来什么能力?
文件读写
开启web服务器
数据库操作
Node.js
Node.js 作为一个 JavaScript 的运行环境,仅仅提供了基础的功能和 API。然而,基于 Node.js 提供的这些基础能,很多强大的工具和框架如雨后春笋,层出不穷,所以学会了 Node.js ,可以让前端程序员胜任更多的工作和岗位:
基于 Express 框架(http://www.expressjs.com.cn/),可以快速构建 Web 应用
基于 Electron 框架(https://electronjs.org/),可以构建跨平台的桌面应用
基于 restify 框架(http://restify.com/),可以快速构建 API 接口项目
读写和操作数据库、创建实用的命令行工具辅助前端开发、etc…
总之:Node.js 是大前端时代的“大宝剑”,有了 Node.js 这个超级 buff 的加持,前端程序员的行业竞争力会越来越强!
理解
Node全名是Node.js (也叫Node,nodejs, node.js),但它不是一个js文件,而是一个软件.
Node,js是一个基于Chrome V8引擎的javascript的运行环境,在这个环境中可以执行js代码
Node.jis提供了大量的内置模块及丰富的第三方模块,能够让我们完成文件读写、Web服务器、操作数据库等功能
为什么前端要学习Node.js
在Node环境下,写js代码实现后端的功能(web服务器,写接口,读写数据库……)
了解后端程序员的工作,增加职场竞争力
它是很多前端框架(vue, react,angular)的运行基础,学好Node.js有助于为后续框架的学习打下基础
Node.js的学习内容
它只是一个环境,不是一门语言(不需要学习新语言),我们要学习它的:
模块系统。能用不同的模块来完成不同的功能,例如:创建web服务器,写接口,连接操作数据库
NPM包管理工具。通过npm来管理我们的需要的第三方包,为后续学习框架打下基础
在Node环境下运行js代码
目标
- 掌握在NodeJS环境下运行js代码的步骤
- 掌握快速打开命令行的窗口的方式
我们前面的学习中,js代码都是在浏览器中运行的,现在开始学习nodejs后,我们有了第二个环境中可以运行js代码。下面来学习如何去运行。
步骤:
- 准备好要被执行的js文件
- 在命令行工具中写命令来运行这个文件
准备一个JS文件
请事先准备好一个js文件。例设这里的路径是:d:/src/index.js
具体内容是
var a = 1;
console.info(a + 2);
打开命令行工具,运行这个文件
格式
node 要执行的文件的路径
注意:node 的后面有一个空格
示例
例如:
node 01.js # 01.js就是当前目录下
node a/01.js # 01.js在目录a下面
- 最好是在当前文件所在目录下来运
在浏览器端
js由三部分组成:ECMAScript + BOM + DOM
es6 ==> ECMAScript 6.0
在nodejs端
有ECMAScript + 内置模块(fs, http, path,…..)。在nodejs中是没有BOM、DOM、window,但使用ECMAScript是通用的
NodeJS中没有DOM,也没有BOM,也没有window对象。
小结
相同点:都是可以运行js代码的容器,更严格一点说:都可以运行ECMAScript
不同点:各有不同的API: nodejs运行js时,不能写DOM,BOM,也不能用window对象了
学习常用的命令行下的命令及按键
考虑到后面一段时间我们将会与这个小窗
命令及键盘按键
node 空格 某个js文件 // 调用 node 程序,运行某个js文件
clear 或者 cls // 清空界面
ls/list/dir // 查看列表(list)
cd 目录名 // 进入到目录中去
cd .. // 返回上一级目录
cd \ // 直接回到根目录
Ctrl+C // 停止 Node 程序
输入部分文件名后按下 Tab 键 // 补全文件名 或 目录名, 多次tab会进行切换
↑ ↓ 上下箭头 // 切换历史输入
nodejs中的模块分类
每个模块都是一个独立的文件。每个模块都可以完成特定的功能,我们需要时就去引入它们,并调用。
nodejs模块的分类:
- 核心模块
- 就是nodejs自带的模块,在安装完nodejs之后,就可以任意使用啦。相当于学习js时使用的Array对象。
- 源代码 https://github.com/nodejs/node/tree/master/lib
- 自定义模块
- 程序员自己写的模块。相当于我们在学习js时的自定义函数。
- 第三方模块
- 其他程序员写好的模块。nodejs生态提供了一个专门的工具npm来管理第三方模块,后面我们会专门讲到。
- 相当于别人写好的函数或者库。例如我们前面学习的JQuery库,artTemplate等。
学习核心模块fs
目标:通过学习核心模块fs,掌握核心模块的基本使用方法
fs是file system的简写
文档
学会查 API,远远比会几个 API 更重要
理解核心模块
核心模块就是 Node 内置的模块,需要通过唯一的标识名称来进行获取。每一个核心模块基本上都是暴露了一个对象,里面包含一些方法供我们使用。一般在加载核心模块的时候,变量(或常量)的起名最好就和核心模块的标识名同名。
例如:const fs = require('fs')
const path = require('path')
console.log(path)
fs模块
fs模块(fs是 FileSystem的简写)是Node.js用来进行文件操作的模块,它属于核心模块。你引入之后就可以直接使用了。
官方手册:http://nodejs.cn/api/fs.html
核心模块的使用步骤:
- 引入模块
// 引入模块
const fs = require('fs');
// 可以使用var、let,但是建议使用const,因为我们不希望它被改变。
// 名字不必都写成FS,一般也就叫fs这个名字。
- 调用api实现自己的要求
fs.apiName()
fs模块中操作文件(或者文件夹)的方法,大多都提供了两种选择:
fs-readFile-同步格式
概念:按照正常顺序来执行代码
格式
同步读取文件语法
const fs = require("fs")
let rs = fs.readFileSync('文件路径',"utf8");
console.log(rs)
const fs = require("fs");
const data = fs.readFileSync("小白.json", "utf8");
console.log(data);
- api的名字后面有Sync(async是异步的,sync表示同步的)
- 不是通过回调函数来获取值,而是像一个普通的函数调用一样,直接获取返回值
同步写文件语法:
const fs =require('fs')
fs.writeFileSync('./data/2.json','你好')
捕获同步格式中的错误对象
如果读成功,则会获取读出来的数据,如果失败了,则会中间后续所有的代码执行。
console.log(1)
let res = fs.readFileSync('errorPath.js')
console.log(res)
console.log(2)
解决方案:用try. catch 结构
const fs = require("fs ");
//希望程序出错了记录日志-发送右键通知
//对于同步代码进行错误处理
// try里面放正常的业务
// catch里面放错误处理业务
try {
let data = fs.readFilesync("./data/dfd.json", "utf8");
console.log("成功");
console.log(data);
} catch (error) {
console.log("错误");
console.log(error.message);
//记录日志信息
//发送邮件通知别人}
}
//try catch 作用进行错误处理=>捕获异常
fs-readFile-异步格式
虽然代码进行了调用但是程序不等待你调用完毕再执行下一步代码
目标: 写代码去读出文件内容,并打印在屏幕上
格式
fs.readFile('文件路径'[,选项], function (err, data) {
if (err) throw err;
console.log(data);
});
说明:
参数1:文件路径。 相对路径和绝对路径均可。
参数2: 配置项,可选参数,可不写。主要用来配置字符集。一般可设置为’utf8‘,如果不设置该参数,文件内容会Buffer形式返回。
参数3: 读取完成后触发的回调函数。这个回调函数在读完文件后自动被nodejs自动调用,并传入 err 和 data
如读取成功,回调函数中的两个参数分别是:
err: null
data: 文件内容,如果不设置参数2,则返回二进制数据。可以使用 toString() 方法将二进制数据
转为正常字符串
如读取失败,回调函数中的两个参数分别是:
err: 错误对象
data: undefined
示例1:读文本内容
const fs = require("fs")
fs.readFile('文件路径',(err, data) => {
if (err) throw err;
console.log(data);
});
上面的data将会是一个Buffer对象类似于数组,它的元素为16进制的两位数,它表示读出来的内容在计算机中的二进制格式。它有一个toString()方法,可以用来把内容以UTF-8的格式转成字符串。
示例2:读文本内容-指定编码格式
const fs = require("fs")
fs.readFile('文件路径', "utf8", (err, data) => {
if (err) throw err;
console.log(data);
});
示例3:读入图片文件
确保你的目录下有图片
const fs = require("fs")
fs.readFile('./img/1.jpg', (err, data) => {
if (err) throw err;
console.log(data);
});
并不是它所有的文件都应该转成字符串的
示例4:体会异步的效果
异步的
const fs = require("fs")
console.log(1)
fs.readFile('文件路径', "utf8", (err, data) => {
if (err) throw err;
console.log(data);
});
console.log(2)
并不是它所有的文件都应该转成字符串的
const fs = require("fs");
fs.writeFile("./data/white.json", "😘", "utf8", function (err) {
if (err) {
console.log("出错了");
console.log(err);
} else {
console.log("成功了");
}
});
示例5:异步错误处理
语法:
// 运行项目的时候 哪怕你的程序前期测试都通过 感觉都没有问题了
// 如果这个项目是真重要 , 都需要人 24小时守在旁边
// setTimeout(() => {
// const a = 123;
// a = 2333;
// }, 5000);
const fs = require('fs');
// 异步代码 有 err对象 进行错误处理
fs.readFile('dsfdsf/sdfdsf.tes', 'utf8', (err, data) => {
if (err) {
console.log('出错');
// 把这个错误信息 记录到 日志文件中!!!
fs.writeFileSync('./data/log.txt', err.message);
// 通过nodejs方式 来发送邮件 到你邮箱中!!!
} else {
console.log('成功');
}
});
结果:
存储错误信息到log.txt中
fs-writeFile-文件覆盖写入
覆盖写入 writeFile
功能:向指定文件中写入字符串, 如果没有该文件则尝试创建该文件。它是覆盖写入:会把文件中的内容全部删除,再填入新的内容。
格式:
fs.writeFile(pathName, content, option, (err)=>{});
// 参数1: 要写入的文件路径 --- 相对路径和绝对路径均可,推荐使用绝对路径
// 参数2: 要写入文件的内容
// 参数3: 配置项,设置写入的字符集,默认utf-8
// 参数4: 写入完成后触发的回调函数,有一个参数 --- err (错误对象)
fs.writeFile(文件路径, 文件内容, 默认是utf8, (err)=>{});
示例1: 写入.txt文件
const fs = require('fs')
fs.writeFile('./a.txt', '小白是笨蛋 \n 换一行', err => {
if (err) {
console.info(err)
throw err
}
})
示例2: 写入json
稍微把问题提升一下,问: 如何把数据写入文件中?
const fs = require('fs')
const data = [{name: '小白', age: 20}]
fs.writeFile('./a.txt', data, err => {
if (err) {
console.info(err)
throw err
}
})
上面的写法会出错: data不是一个字符串或者是Buffer
const fs = require('fs')
const data = [{name: '小白', age: 20}]
fs.writeFile('./a.txt', JSON.stringify(data), err => {
if (err) {
console.info(err)
throw err
}
})
附:fs模块中的常用方法
API | 作用 | 备注 |
---|---|---|
fs.access(path, callback) | 判断路径是否存在 | |
fs.appendFile(file, data, callback) | 向文件中追加内容 | |
fs.copyFile(src, callback) | 复制文件 | |
fs.mkdir(path, callback) | 创建目录 | |
fs.readDir(path, callback) | 读取目录列表 | |
fs.rename(oldPath, newPath, callback) | 重命名文件/目录 | |
fs.rmdir(path, callback) | 删除目录 | 只能删除空目录 |
fs.stat(path, callback) | 获取文件/目录信息 | |
fs.unlink(path, callback) | 删除文件 | |
fs.watch(filename[, options][, listener]) | 监视文件/目录 | |
fs.watchFile(filename[, options], listener) | 监视文件 | |
fs.existsSync(absolutePath) | 判断路径是否存在 |
课堂案例1
const fs = require("fs");
/*
1 使用文件读写 读 来获取 list.json 内容 数组
2 执行 数组push元素
3 重新把数组 写 会到源文件中
*/
//lidy.jdon初始内容=[{"name":"小白"}]
// json 字符串
let list = fs.readFileSync("./data/list.json", "utf8");
list = JSON.parse(list); // 把字符串 又转回数组
list.push({ name: "小白+1" });
// console.log(list);
// 把数组 重新写一次到 文件中 记得数组 转成字符串 json
fs.writeFileSync("./data/list.json", JSON.stringify(list));
读写作业1
const fs = require("fs");
const list = [{ name: "小白", skinname: "女王" }];
// 数组转成字符串
// list.join()
// JSON
// 要接收的内容 字符串格式
fs.writeFileSync("./data/list.json", JSON.stringify(list));
/*
1 使用文件读写 读 来获取 list.json 内容 数组
2 执行 数组push元素
3 重新把数组 写 会到源文件中
*/
// json 字符串
let list1 = fs.readFileSync("./data/list.json", "utf8");
list1 = JSON.parse(list1); // 把字符串 又转回数组
list1.push({ name: "小白白", skinname: "女王" });
// console.log(list1);
// 把数组 重新写一次到 文件中 记得数组 转成字符串 json
fs.writeFileSync("./data/list.json", JSON.stringify(list1));
const data = fs.readFileSync("./data/list.json", "utf8");
console.log(data);
服务器相关概念
http是nodejs的核心模块,它能让我们能够通过简单的代码创建一个Web服务器,处理http请求。
用http 模块写一个简单的web服务器
http模块在线文档:https://nodejs.org/dist/latest-v14.x/docs/api/http.html
目标
用http模块写一个简单的服务器
要点
- 引入http核心模块
- 使用createServer来创建服务
- 使用listen来启动服务
操作
第一步:新建一个文件,名为 d:/src/http.js
( 文件名及路径名可以自行设置,建议均不使用中文字符), 内容如下
// 创建我们第一个web服务器
// 1.0 导入http模块
const http = require('http');
// 2.0 创建一个服务
let server = http.createServer((req, res) => {
console.log('接收到了客户端请求');
res.end('OK');
})
// 3.0 监听8001端口并启动web服务器等待客户端请求
server.listen(8001, () => {
console.log('web服务器准备就绪:127.0.0.1:8001可以访问');
})
// 1 引入核心模块 内置模块 http
const http = require("http");
// 2 通过模块来创建一个服务器对象
// request表示请求客户端发送给服务器的请求 里面有请求的方式请求的ur1 请求的参数请求头
// response表示服务器要响应什么数据给前端响应http状态码200 404响应数据回去
const app = http.createServer((request, response) => {
// 设置一个响应头 才可以发送中文编码
response.setHeader("content-type", "text/html;charset=utf8");
//设置服务器 响应数据给前端
response.end("小白是笨蛋");
});
// 3 开始运行服务器
//一个电脑上有好多端口0到6553端口已经被占用了1/不要太小端口-系统软件给占用!!
// 3000 以上都可以
//本地电脑的地址 http://127.0.0.1
//本地电脑的地址 http://locahost
app.listen(3000, () => {
console.log("3000服务器已开启");
});
第二步:运行js代码。
在小黑窗中进入到d盘根目录,键入命令 node http.js
,此时会弹出一个小黑窗,不要关。
第三步:本地验收
打开一个浏览器页面,输入’http://localhost:8081',观察效果:
- 浏览器中的效果
- 小黑窗中的效果
第四步:共享地址
把localhost改成你自己电脑的ip地址,再把这个路径发你的同学(同一个局域网)来访问。
第五步:停止服务
ctrl + c
如果不能访问,有可能你需要手动关闭你自己计算机的防火墙。