Day 1
1. Node.js 是什么
- Node.js 不是一门语言,是一个 JavaScript 运行时环境,简单来讲,就是以前只有浏览器可以解析和执行 JavaScript 代码,现在可以脱离浏览器用 Node.js 来执行。
- 学习 Node.js 的目的是为了打开服务器这个黑盒子,更好地配合服务端开发人员进行协同开发。
- Node 只有 ECMAScript,没有 DOM 和 BOM。
2. Node.js 的安装与调试
2.1 安装
- 下载 node.js:http://nodejs.org/en/download/
- 安装
- 确认 Node 环境是否安装成功
- 打开命令行,输入
node --version
- 或者
node -v
- 打开命令行,输入
2.2 调试
有三种方法:
- 调用系统命令行工具(windows快捷键WIN+R),输入CMD,将路径调整到要调试的 js 文件所在目录,输入
node foo.js
即可进行调试。 - 事前安装有 git 工具的,可在 js 文件所在目录右键,选择
Git Bash Here
,在打开的窗口中输入node foo.js
即可进行调试。 - 在 js 文件所在目录,按住“shift”后右键,选择“在此处打开powershell窗口”,在打开的窗口中输入
node foo.js
即可进行调试。
使用 visual studio 打开 js 文件的,可以使用 vs 内置的调试工具进行调试。
3. 模块系统
3.1 核心模块
-
核心模块是由 Node 提供的一个个具名的模块,它们都有特殊的名称标识,例如:
- fs:文件操作模块
- http:网络服务构建模块
- os:操作系统信息模块
- path:路径处理模块
-
所有核心模块在使用前都要使用
require
方法来加载,方可使用。var fs = require('fs')
-
以 fs 为例,加载 fs 核心模块后,可以使用其中的
fs.readFile()
方法读取文件,也可使用fs.writeFile()
方法写入文件。
3.2 自定义模块
除了具名的核心模块,还有用户自己编写的文件模块,同样通过 require
方法加载(下例为在 a 模块中加载 b 模块,并导出 b 中的 foo):
// 【a.js】
// 1. 加载自定义的 b 模块
var ret = require('./b.js')
// 2. 导出 b 中的 foo
console.log(ret.foo)
// 【b.js】
// 将 foo 用 exports 方法导出
exports.foo = 'ccc'
- 在 Node 中没有全局作用域的概念,只能通过
require
方法来加载执行多个 JavaScript 脚本文件。 - 文件与文件之间由于是模块作用域,所以不会有污染的问题,模块是完全封闭的,外部无法访问内部,内部也无法访问外部。
- 当模块之间需要通信时,可以利用
exports
对象将成员导出。
4. 服务器开发
4.1 创建服务器
// 1.加载 http 核心模块
var http = require('http')
// 2.使用 http.createServer() 方法创建一个 Web 服务器
var server = http.createServer()
// 3.注册 request 请求事件,当客户端有请求过来,就会触发服务器的 request 请求事件
server.on('request', function (){
console.log('收到客户端的请求')
})
// 4.绑定端口号,启动服务器
server.listen(3000, function () {
console.log('服务器启动成功了,可以通过http://127.0.0.1:3000来进行访问')
})
4.2 发送响应
// request 请求事件处理函数需要接受两个参数:
// 1. request 请求对象,用来获取客户端的一些请求信息,如请求路径
// 2. response 响应对象,用来给客户端发送响应消息
server.on('request', function(request, response) {
console.log('收到客户端的请求, 请求路径是' + request.url);
// 此时在浏览器中输入 http://127.0.0.1:3000/a/b,这里的 /a/b 即请求路径
// 可以根据不同的路径来选择性响应不同的内容
// response 对象有一个方法 write 可以用来给客户端发送响应数据
// write 可以使用多次,但是最后一定要使用 end 来结束响应,否则客户端会一直等待
response.write('hello');
response.write(' node.js');
response.end();
// write 和 end 可以合并为 end,如 response.end('hello world')
})
4.3 根据不同请求路径返回数据
server.on('request', function(req, res) {
// 3.1 获取请求路径
var url = req.url;
// 3.2 通过判断,根据不同的 url 返回不同的结果
if (url === '/') {
res.end('index page');
} else if (url === '/a') {
res.end('hello world');
} else {
res.end('404 Not Found');
}
})
4.4 响应内容类型(Content-Type)
- 浏览器接收服务器发送的文件,其本质上是一堆字符串,因此,服务器在发送响应时,要告诉浏览器应该用什么方式解析文件。
- 不同资源对应的 Content-Type 是不一样的:
- 文本文字是:
text/plain
- html 文件是:
text/html
- jpeg 图片是:
image/jpeg
- 文本文字是:
server.on('request', function(req, res) {
res.setHeader('Content-Type', 'text/plain; charset=utf-8');
res.end('hello 世界'); // 正常打印出"hello 世界"
})
- 在遇到接收中文文字内容时,需要指定编码方式,如
charset=utf-8
。 - 请求图片文件时,不用指定编码,指定了反而会出错。
- 更多的文件类型可以查询: http://tool.oschina.net/commons
4.5 IP地址和端口号
- IP地址用来定位计算机。
- 端口号用来定位具体的应用程序,一些需要联网通信的软件都会占用一个端口号,范围从 0 - 65536 之间。
- 在计算机中有一些默认的端口号,最好不要去使用,如 http 服务的 80。
- 可以同时开启多个服务,但一定要确保不同服务占用的端口号不一致,即同一个端口号同一时间只能被一个程序占用