Node介绍
- node 是一个开发平台, 就像 Java 开发平台、.Net 开发平台、PHP 平台、Apple 开发平台一样。
- 何为开发平台? 有对应的编程语言、有语言运行时、有能实现特定功能的 API (例如: fs http path)
- 该平台使用的编程语言:javascript 语言.
- node.js 平台是基于谷歌 V8引擎构建的
- 基于 node.js 可以开发控制台程序(命令行程序)、桌面应用程序(借助 electron 、node-webkit等框架实现)、Web 应用程序(网站)
#Node的特点
事件驱动(事件触发,会执行回调函数里面的代码)
- js也是事件驱动,鼠标放置,点击,触发不同的事件执行对应的代码
- onclick = function(){}
- node.js 是传一个回调函数
2.非阻塞(I/O)
- I/O就是输入输出的操作
- 读写I/O+网络I/O
- nodejs 的I/O 不会阻塞程序
1 | //引入模块 |
- 不会阻塞我们主程序的运行
- 单线程;
- 首先我们 js 就是单线程的语言, node基于 js 也是单线程;
- 减少内存开销 (线程/2M)
- 拥有世界最大的开源生态系统– npm
- npm - 开源库托管网站! 官网
- 我们 node是一个开发平台有 实现特定功能的 api, 但是内置的 api 是有限的,,想要实现 node.js 自己实现不了的功能怎么办 ?? 就去找 npm,,
- 只要是我们想到的功能,都已经有人帮我们已经写好了,就在 npm 这个代码仓库里,,,
- npm 这个丰富的开源系统,,而且也很开放, 也都会写模块,,然后把代码上传到 npm 上,供大家使用
- 就像 jquery 一样,很多人都给它写插件啊,,给她拓展功能啊,
- 我们 node.js 也是,,,, npm 里面帮我们node拓展了各种各样的功能包
#Node 创建 文件名命名常用规范
- 不要用中文 (特别里面是使用 npm 安装包的时候: npm init -y)
- 不要包含空格
- demo里可以 项目总切记不要
- 不要出现node关键字
- 建议以 ‘ - ‘ 分割单词 (例如: child-demo.js )
Node 编写代码常用规范
- 命名: 变量名和函数名命名,按照驼峰命名 —— var userName = ‘123’
- 优先使用 const(常量) 和 let (变量)
- 引入: 引入模块时,变量名最好和模块名一样:
var fs = require('fs')
; - 尽量使用单引号 ,, json数据里使用双引号
- 动态字符串使用 反引号 :
1
`你好啊 ${name}` ''
- 空格: 操作符前后需要加空格, 比如 + - * / =
var foo = 'bar' + 'baz'
- 分号: 表达式结尾添加分号,,,虽然编译器自动会给我们,可能会带来一些错误!
1 | var x = 1; |
案例 1. 编写 Hello world 在 node 环境下执行
- 创建
hello-world.js
文件 - 编写:
console.log('hello world')
- 终端打开:
node hello-world.js
运行即可 (在 node环境下运行)
1 | 注意1: node + 文件名 / 路径 |
###案例 2: 文件读写案例
1 | /** |
读取文件
读取文件 :
fs.readFile(file, [, options], callback);
常用:
fs.readFile ( where , encoding , callback )
- 参数1: 从哪里读取数据? 必填
- 参数2: 以什么格式读取出来 ?
- 参数3: 读取完毕后的回调函数, 必填
- 读取文件注意:
- 该操作也是 异步操作;
- 回调函数有2个参数:
err
和data
- 如果读取文件时没有指定编码,那么返回的将是原生的二进制数据
;如果指定了编码,那么会根据指定的编码返回对应的字符串数据。
1 | // 问题1: |
同步读取文件
- 方法:
fs.readFileSync(path[, options])
- 返回值 接收数据
- // fs.readFileSync(path[, options])
// 参数1: 从哪里读取文件
// 参数2: 编码 (可选)
1 | console.log(哈哈) |
try…catch (捕获异常 , 抛出错误)
1 | // 一旦出错,后面的代码不执行了.. |
异步读文件
###throw errr (捕获异常 , 抛出错误)
问题: 同步没有 err , 能不能不捕获异常了???
1 | no |
- 同步: try catch
1 | 异步不能使用 try..catch 因为不管正确和错误都会走回调 |
路径
- __dirname
1 | //1. 加载 fs 模块 |
通过 node.js 编写 http 服务程序 - 极简版本
步骤
加载 http 模块;
创建 http 服务;
监听 request 事件 —— 为 http 服务对象添加 request 事件处理程序;
启动服务,开始监听 —— 开启 http 服务监听,准备接收客户端请求;
*注意
浏览器可能是乱码, 需要设置 浏览器显示时所使用的编码
1
response.setHeader('Content-Type','text/plain ; charset=utf-8'); // 注意 后面的分号 和引号的位置
- 演示一下设置
Content-Type=text/html
和Content-Type=text/plain
的区别。 - request 对象 包含了用户请求报文中的所有内容,通过 request 对象可以获取所有用户提交过来的数据;
- response 对象用来向用户响应一些数据,当服务器要向浏览器响应数据的时候必须使用 response 对象
- 有了 request 对象和 response 对象,就既可以获取用户提交的数据,也可以向用户响应数据了
- 演示一下设置
1 | //1. 加载 http 模块 |
简化: 创建、开启、监听 一步走
1 | //2. 创建 开启 监听 |
text/plain 和 text/html 的区别
1 | response.setHeader('Content-Type','text/plain ; charset=utf-8'); // 注意 后面的分号 和引号的位置 |
编写 http 服务程序 — 根据 不同的路径 url 请求 响应不同的 : 纯文本
注意:
根据
req.url
的不同来判断 (例如: /abc /index )别忘了
404
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44/**
* 编写 http 服务程序 — 根据 不同的 url 请求 响应不同的 : 纯文本
* 1. 编写 http 服务程序
* 2. 获取不同的 url
* 3. 响应不同的纯文本
*/
//1. 加载 http 模块
var http = require('http');
//2. 创建.开启.监听
http.createServer(function(req,res){
// 设置文件类型 和 编码格式
res.setHeader('Content-Type','text/plain;charset=utf-8');
console.log(req.url);
// / index --> hello index
// /login --> hello login
// /register --> hello register
// /list --> hello list
if (req.url=='/' || req.url == '/index') {
res.end('hello index')
} else if(req.url=='/login') {
res.end('hello login')
}else if(req.url=='/register') {
res.end('hello register')
}else if(req.url=='/list') {
res.end('hello list')
}else{
res.end('hello 404 page not found')
}
}).listen(8080,function () {
console.log('服务开启了');
})
Common System Errors - 常见错误号
- EACCESS (Permission denied)
- An attempt was made to access a file in a way forbidden by its file access permissions.
- 访问被拒绝
- EADDRINUSE (Address already in use)
- An attempt to bind a server (net, http, or https) to a local address failed due to another server on the local system already occupying that address.
- 地址正在被使用(比如:端口号占用)
- EEXIST (File exists)
- An existing file was the target of an operation that required that the target not exist.
- 文件已经存在
- EISDIR (Is a directory)
- An operation expected a file, but the given pathname was a directory.
- 给定的路径是目录
- ENOENT (No such file or directory)
- Commonly raised by fs operations to indicate that a component of the specified pathname does not exist – no entity (file or directory) could be found by the given path.
- 文件 或 目录不存在
- ENOTDIR (Not a directory)
- A component of the given pathname existed, but was not a directory as expected. Commonly raised by fs.readdir.
- 给定的路径不是目录