0 NodeJS背景
0.1 NodeJS是什么
我们先看看官网上如何评价
- Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。
- Node.js 使用了一个事件驱动、非阻塞式 I/O 的模型,使其轻量又高效。
首先为什么说是基于Chrome V8 引擎?
因为在此之前js只能作为前端开发,并且运行在浏览器中。直到Chrome V8 引擎出现才把js分离出来运行在后台。其中Chrome V8 引擎可以理解为JVM,是js的运行环境。
0.2 NodeJS和JS有什么区别
其实两者底层基本一样,语法都是基于ECMAScript。
- NodeJS
- 没有BOM和DOM操作。
- 提供了一些os(操作系统)、file system(文件系统)、net(网络系统)、database(数据库)的API。
- 直接运行在命令窗口,需要NodeJS环境。
- WebJS
- 具有BOM和DOM操作。
- 不具有其他的服务端API。
- 运行在浏览器上。
我们可以在这里查看Node的API。
0.3 NodeJS安装
去官网下载之后下一步下一步即可
运行脚本方法:
node 文件.js
1 NodeJS基本用法
1.1 NodeJS读取文件
在操作文件之前我们先引用包(类似于java中引用jar包)
var fs = require(‘fs’)
这里的fs
就是我们的操作文件包
写文件
拿到fs对象后调用writeFile
方法
具体代码参考如下1
2
3
4
5
6
7
8
9var fs = require('fs');
// 第一个参数:文件路径
// 第二个参数:文件内容
// 第三个参数:回调函数
// 成功时:error是null
// 失败时:error是错误对象
fs.writeFile('./data/test.md',"hello word",function(error) {
console.log('文件写入成功')
})读文件
拿到fs对象后调用readFile
方法
具体代码参考如下1
2
3
4
5
6
7
8
9
10
11
12
13var fs = require('fs');
// 第一个参数:文件路径
// 第二个参数:回调函数
// 成功时:error是null,data是对象
// 失败时:error是错误对象,data是空
fs.readFile('./data/test.md',function(error,data) {
// 这里返回的是二进制数据,我们需要通过toString方法把其转换为我们认识的字符
if(error){
console.log('文件读取失败了')
}else{
console.log(data.toString())
}
})
1.2 HTTP核心模块
- 加载http核心模块
- 使用htto.createServer()方法创建一个web服务器,返回一个Server实例
- 服务器可以接收请求和发送请求
- 通过request.url判断请求路径
- 通过response.write()来发送相应数据(
一定要使用end结束,否则客户端会一直等待
)
- 绑定端口号,启动服务
我们参考下面代码1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19// 加载http核心模块
var http = require('http')
// 使用http.createSrever()方法创建一个web服务器,返回一个Server实例
var server = http.createServer();
// 服务器可以接收请求和发送请求
server.on('request',function(request,response) {
console.log('收到客户端的请求了');
// 通过request.url判断请求路径
console.log('收到客户端的请求路径是'+request.url);
// 发送返回数据
response.wirte('hello');
// 结束会话
response.end();
// 上面的方法也可以这么写 response.end('hello');
})
// 绑定端口号,启动服务
server.listen(3000,function() {
console.log('服务启动了');
})
根据不同路径判断输出不同的值
响应只能是字符串或二进制,所以我们需要把JSON转成字符串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// 加载http核心模块
var http = require('http')
// 使用http.createSrever()方法创建一个web服务器,返回一个Server实例
var server = http.createServer();
// 服务器可以接收请求和发送请求
server.on('request',function(request,response) {
var url = request.url;
if(url === '/'){
response.end('index')
}else if(url === '/login'){
response.end('login')
}else if(url === '/products'){
var products = [
{
name:'12',
price: 12,
},
{
name:'22',
price: 22,
},
]
// 响应只能是字符串或二进制,所以我们需要把JSON转成字符串
response.end(JSON.stringify(products));
}else{
response.end('404')
}
})
// 绑定端口号,启动服务
server.listen(3000,function() {
console.log('服务启动了');
})
1.3 其他API
获取机器信息
直接看代码1
2
3
4
5
6//用来获取机器信息的
var os = require('os');
//获取当前机器的cpu
console.log(os.scpus());
//获取内存
console.log(os.totalmem());操作路径
直接看代码1
2
3
4//用来获取机器信息的
var path = require('path');
//获取一个路径中的扩展部分
console.log(path.extname('c:/a/b/c/d/hello.text'));
2 Node中的几点说明
2.1 模块化编程
首先现在js无论前端还是后端都是模块化编程,ES6中用import
和export
来进行模块导入导出
在nodeJS中我们用require
和export
来实现导入导出
- require是一个方法,它是用来加载模块的
- node中有两种模块
- 具名的核心模块(fs,http)
- 用户自己编写的的文件模块
- 相对路径必须加
./
- 不过可以省略后缀名(.js)
- 在Node中,没有全局作用域,只有模块作用于
- 外部访问不到内部
- 内部也访问不到外部
- exports可以把所需要的被外部访问的成员在此定义
- exports默认是一个空对象
我们来看一个例子,创建两个js(a.js,b.js)1
2
3
4
5
6
7
8
9var foo = 'aaa'
console.log('a start')
function add(x,y){
return x + y;
}
var ret = require('./b,js')
console.log(ret.foot) // 调用b中变量
console.log(ret.add(10,30)) // 调用b中变量
console.log('a end')
- exports默认是一个空对象
1 | console.log('b start') |
2.2 模块化编Content-Type
在我们发送返回消息(response)的时候,我们返回给浏览器信息时通常加上请求头
response.setHeader(‘Content-Type’,’text/html; charset=utf-8’)
- Content-Type我们可以理解为header的Key
- text/html传输的文本类型
- charset=utf-8传输的字节编码,这里为utf-8
这时候我们可以再浏览器返回值值中查看如图所示:
请看下面一段代码1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23// 加载http核心模块
var http = require('http')
// 使用http.createSrever()方法创建一个web服务器,返回一个Server实例
var server = http.createServer();
// 服务器可以接收请求和发送请求
server.on('request',function(request,response) {
var url = request.url;
if(url === '/plain'){
// text/plain就是普通文本
res.setHeader('Content-Type','text/plain; charset=utf-8');
response.end('hello 世界')
}else if(url === '/html'){
// text/html就是html标记语言,浏览器会进行渲染
res.setHeader('Content-Type','text/html; charset=utf-8');
response.end('<p>hello world <a herf="">点击</a></p>')
}else{
response.end('404')
}
})
// 绑定端口号,启动服务
server.listen(3000,function() {
console.log('服务启动了');
})
而我们通查不把HTML写在js中,而是通过fs模块进行读取.html
1 | // 加载http核心模块 |
Content-Type的更多类型请点击这里
3 NodeJs实现服务器
3.1 访问路径访问本地数据
这里我们可以通过http获取访问的路径,之后用fs来读取我们该路径下固定文件夹下的具体文件1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24var http = require('http')
var fs = require('fs')
var server = http.createServer();
// 定义访问路径
var wwwDir = 'D:/Movie/www'
server.on('request',function(request,response) {
var url = request.url;
var filePath = '/index.html';
if(url !== '/'){
filePath = url;
}
fs.readFile(wwwDir + filePath,function(err,data) {
if(err){
res.setHeader('Content-Type','text/plain; charset=utf-8');
response.end('文件读取失败')
}else{
res.setHeader('Content-Type','text/html; charset=utf-8');
response.end(data)
}
})
})
server.listen(3000,function() {
console.log('服务启动了');
})
3.2 替换模板文件
要做到替换模板文件我们需要做两个操作
- 得到wwwDir目录列表中的文件名和目录名(fs.readdir)
- 将得到的文件名和目录名替换到template.html中
- 在template.html中需要替换的位置预留一个特殊标记
- 根据files生成需要的HTML内容
我们创建一个.html,下面是一段代码片段1
2
3<td data-value="apple/">
<a class="icon dir" herf="D:/Movie/www/apple/">^-^</a>
</td>
我们把^-^特殊标记替换成我们自己想要的名字
可以用replace替换1
2
3data = data.toString()
data = data.replace('^-^','苹果')
res.end(data)
3.3 Art-Template
我们用art-template插件来完成替换功能,官网
art-template既可以用在web上也可以用在Nodejs中
art-template是将文件看成字符串,即使在js中的模板也会被替换掉,至于执行js那是浏览器的事儿
- 安装
- npm install art-template
- 该命令在哪里执行就会把包下载到哪里。默认下载到node_moudules目录中
- web引用
1 |
|
- Node引用
- 在需要使用的地方加载art-template模块
1 | var template = require('art-template') |
3.4 改进服务器代码
1 | var http = require('http') |
3.5 静态文件资源
作为我们的服务端,不可能让用户能访问我们所有的文件,所以我们需要管理哪些资源用户可以访问,哪些不可以,能访问的就是我们所谓的静态资源
当我们访问服务器发生了以下几个重大事件
1.浏览器服务器
2.服务器读取模板文件
3.模板文件替换后在浏览器中渲染
4.浏览器运行代码,当读到link,script等标签时需要再去服务器获取资源
5.服务器判断请求路径是否可以访问
1 | var http = require('http') |
这里还需要说明一下,我们在模板引擎中的link,script标签,引用地址应该是一个相对路径一个url地址,而不是绝对的了
因为在浏览器真正发送请求的时候会把http://127.0.0.1:3000拼上1
<link rel="stylesheet" href="/public/lib/...."
同理我们的a标签引用如果是页面内部调整也需要考虑到服务器,比如跳转到首页我们可以这样写
1 | <a href="/"></a> |
4 案例整合
通过这些知识,我们用一个留言板的案例来整合所学习的知识
4.1 HTML模板部分
我们用Art-Template来作为我们的模板
- 消息列表页面
1 | <div class="comments container"> |
- 添加消息页面
1 | // 表单中需要提交的元素必须具有name属性 |
4.2 url.parse()
url.parse()用来解析url和参数我们可以在命令行输入node进入node环境测试
- node
- url.parse(‘http://127.0.0.1:3000/pinglun?name=zhangsan&message=1234456')
结果如图所示
结果如图所示
可以看出url.parse不近能帮我们解析出url还能帮我们解析出参数
4.3 NodeJs部分
1 | var http = require('http') |
最后更新: 2018年12月16日 14:09