Node.js 是由C++编写,构建在Chrome v8引擎下,是让js运行在服务端的运行环境。没有浏览器安全级的限制,提供系统级别的API:(1)文件读写(2)进程的管理(3)网络通信
官方网站:
https://nodejs.org/en/
http://github.com
http://npmjs.com
技术问答社区: https://stackoverflow.com/
安装路径:https://www.runoob.com/nodejs/nodejs-install-setup.html 偶数为稳定版本0.6x, 0.8x, 0.10.x,基数为非稳定版本0.5x, 0.7x, 0.9x
特性:
- 事件驱动
- 非阻塞 I/O
Node.js特性适合高并发、I/O密集的场景。
基础概念:
CPU密集:压缩、解压、加密、解密
I/O密集:包括文件操作、网络操作、数据库,因为有静态资源的读取、数据库操作、渲染页面
高并发:在单位时间内访问量特别大
单核CPU:计算机在极短时间内切换不同的指令,使得单核CPU看起来能处理多个任务。
线程:进程内一个相对独立,可调度的执行单元,同属于一个进程的线程共享进程资源。
单线程:一个进程中只有一个线程,进程的资源都归这一个线程所用。
多线程:一个进程中有多个线程,多个线程可以一起执行多个任务。
Node.js工作模型:
- 传统的服务器处理web请求,每一个I/O操作配置一个CPU,面对每个请求服务器都要开一个进程, CPU利用率低。Node.js模型就相当于一个CPU服务多个I/O操作,服务器只开一个进程,不一定按照顺序,哪个I/O操作先完成,哪个请求就先执行回调函数,CPU利用率大大提高。
1.创建http服务器
//1.引入http模块
var http = require('http');
var host = '127.0.0.1';
var port = 8888;
//2.创建http服务
//根据客户端(浏览器)请求的地址不同,向前端发送不同的数据,只要接收到客户端的http请求,就会触发该回调函数
var server = http.createServer(function (req, res){
//req 请求对象, res 响应对象
//req.url:保存的是请求的路径信息
//req.method:保存的是请求方法
//通过res.write()向客户端发送数据、页面
res.statusCode = 200;
res.setHeader('ContentType', 'text/plain');
if (req.url === '/index') {
res.write('welcome to index');
} else if (req.url === '/login') {
res.write('please login');
}
//响数据返回完成时,断开连接
res.end();
});
//3.监听端口
server.listen(port, host, function () {
//启动服务时会执行
console.log(`load success,${host}:${port}`);
});
2.fs模块使用
// 引入fs模块,fileSystem
var fs = require('fs');
// fs文件目录操作
(1)fs.exists,文件是否存在
// fs.exists(目录名, 回调函数),判断目录是否存在
// 第一个参数为要判断的目录路径,第二个参数为回调函数,result为boolean类型,表示目录是否存在
fs.exists('./demo.txt', function (result) {
if (result) {
console.log('改目录存在');
} else {
console.log('该目录不存在');
}
});
(2)fs.realpath,文件的绝对路径
// fs.realpath(相对路径, 回调函数(错误信息, 绝对路径)), 通过相对路径获取绝对路径
fs.realpath('./demo.txt', function (err, path) {
if (err) {
console.error('绝对路径获取失败', err);
} else {
console.log('绝对路径为:' + path);
}
});
(3) fs.rename,更改文件名称
// fs.rename(源文件路径, 新文件路径, 回调函数(错误信息))
fs.rename('./demo.txt', './data.txt', function (err) {
if (err) {
console.error('重命名失败', err);
} else{
console.log('重命名成功');
}
});
(4)fs.readFile,读取文件内容
// 文件读写操作
// fs.readFile(文件路径, [以什么格式读取,可选,默认为buffer对象],回调函数(错误信息, 文件内容) )
fs.readFile('./demo.txt', 'utf-8', function(err, content){
if (err) {
console.error('文件读取失败', err);
} else {
console.log('文件内容为:', content);
}
});
(5) fs.writeFile,写文件
// fs.writeFile(文件路径, 写入内容, 写入控制, 回调函数),如果文件不存在时,会根据路径新建文件
fs.writeFile('./demo.txt', 'wahaha哈', {flag: 'a'}, function(err){
// flag: 'a'表示拼接
// flag: 'w'表示覆盖
if (err) {
console.error('文件写入失败', err);
} else {
console.log('文件写入成功');
}
});
(6)复制文件
// 文件复制: 1.以默认方式读取文件内容,2,在新建文件中,以默认方式写入内容
fs.readFile('./a.png', function(err, content){
if (err) {
console.error('文件读取失败', err);
} else {
fs.writeFile('./a副本.png', content, {flag: 'w'}, function(err){
if (err) {
console.error('文件复制失败');
} else {
console.log(文件复制成功);
}
});
}
});
(7)fs.createReadStream,以64K为单位片段读取文件
var fs = require('fs');
// 创建读取管道流
var rs = fs.createReadStream('./demo.txt');
var temp = '';
//每读取到64K文件时,触发该事件,通过该事件函数获取读取到的文件内容
rs.on('data', function (chunk){
temp += chunk;
console.log('读取到的片段为:', chunk);
});
// 当文件读取完成后,触发该事件
rs.end('data', function (){
console.log('文件内容为:', temp.toString());
});
(8)fs.createWriteStream,以64K为单位片段写入文件
var fs = require('fs');
// 创建写入管道流
var ws = fs.createWriteStream('./hello.txt');
ws.write('我们的明天会更好!');
(9)用流方法复制文件
var fs = require('fs');
// 创建读取管道流
var rs = fs.createReadStream('./demo.txt');
// 创建写入管道流
var ws = fs.createWriteStream('./demo副本.txt');
//第一种方法,读取到的内容写入文件;但是写入速度明显慢于读取速度,为了内存利用率更高,可以牺牲读取的速度实现第二种方法。
/* rs.on('data', function(chunk){
ws.write(chunk);
}); */
//第二种方法,pipe方法写入数据时,会等当前读取出的数据全部写入后,才进入下一次读取操作,内存利用率高,但读写时间长
rs.pipe(ws);
3.http模块详解
(1)获取请求接口,根据请求接口发送对应的页面
<!--这是index.html-->
<!DocType html>
<html>
<head>
<meta charset="utf-8"></meta>
<title>首页</title>
</head>
<body>
这是首页哦!
</body>
</html>
<!--这是login.html-->
<!DocType html>
<html>
<head>
<meta charset="utf-8"></meta>
<title>登录</title>
</head>
<body>
这是登录页面哦!
<form action="/login" method="get">
<input type="text" name="username" />
<br />
<input type="password" name="password" />
<br />
<input type="submit" vaule="登录" />
</form>
</body>
</html>
var http = require('http');
var fs = reuqire('fs');
var url = require('url');
var server = http.createServer(function (req, res){
var urlObj = url.parse(req.url, true);//将请求的url属性转换为url对象,第二个参数设置为true,接口参数会转换为对象
console.log(urlObj );
if (urlObj.pathname === '/index.html') {//访问index.html
//读取index.html,将文件中的内容以流的形式返回给客户端(浏览器)
var rs = fs.createReadStream('./index.html');
rs.pipe(res);// 数据返回完毕后自动断开
} else if (urlObj.pathname === '/login.html') {//访问login.html
var rs = fs.createReadStream('./login.html');
rs.pipe(res);// 数据返回完毕后自动断开
} else if (urlObj.pathname === '/login') {//点击登录
// query对象为get方法发送的参数对象
if (urlObj.query.username === '123' && urlObj.query.password === '123') {
res.write('用户登录成功!')
} else {
res.write('用户登录失败!')
}
res.end();// 表示后端数据返回完毕,断开请求
}
});
server.listen(8888, function(){
console.log('load success');
})
(2)接收POST提交的参数
<!--这是login.html-->
<!DocType html>
<html>
<head>
<meta charset="utf-8"></meta>
<title>登录</title>
</head>
<body>
这是登录页面哦!
<form action="/login" method="post">
<input type="text" name="username" />
<br />
<input type="password" name="password" />
<br />
<input type="submit" vaule="登录" />
</form>
</body>
</html>
安装querystring
// 在命令窗口执行
npm install querystring
var http = require('http');
var fs = require('fs');
var url = require('url');
var qs = require('querystring');
var server = http.createServer(function(req, res){
var urlObj = url.parse(req.url);
if (urlObj.pathname === '/login.html') {
var rs = fs.createReadStream('./login.html');
rs.pipe(res);
} else if (urlObj.pathname === '/login') {
var temp = '';
// 用流的方式读取请求头传来的参数
req.on('data', function(chunk) {
temp += chunk;
});
req.on('end', function () {
console.log(temp.toString());// username=123&password=123
var query = qs.parse(temp.toString());// 将post方法传来的参数转换参数对象
//{username: '123',password: '123'}
if (query.username === '123' && query.password === '123') {
res.write('用户登录成功');
} else {
res.write('用户登录失败');
}
res.end();// 断开连接
});
}
});
server.listen(8888, function () {
console.log('load success');
})
(3)html文档中引入外部文件的处理方法,该方法只适用于静态页面
<!--这是demo.html-->
<!DocType html>
<html>
<head>
<meta charset="utf-8"></meta>
<title>demo</title>
<link rel="stylesheet" href="./demo.css">
</had>
<body>
这是demo页面哦!
</body>
</html>
var http = require('http');
var fs = require('fs');
var server = http.createServer(function (req, res) {
var urlObj = url.parse(req.url);
var path = '.' + urlObj.pathname;
var bool;
bool = fs.existsSync(path);// 判断文件是否存在
if (bool) {// 如果存在该文件,将文件内容发送给客户端(浏览器)
var rs = fs.createReadStream(path);
rs.pipe(res);
}
});
server.listen(8888, function(){
console.log('load success');
})