前言
node.js是后端的语言 我们知道的apache 服务器 才能支撑一些代码 但是 node.js是一个独立的环境(node.js本身就是一个平台)这个就是为什么很多小程序和app是直接使用它的
nodejs的特点 :
1、单线程 :一次node 只能执行一次服务功能
2、异步,非阻塞 :虽然一次只能开启一次服务但是 但是缺可以处理许多内容 异步好比 你可以在执行 http 请求 响应的同时使用 文件操作系统
3、跨平台性
4、多态 : 可以使用 nmp命令下载相应的资源库
node.js的准备工作安装 :
Node.js — Download Node.js®
下载安装
使用 node -v
nmp -v 不报错就证明环境安装好了
一、node.js 创建第一个应用
// 创建第一个服务器程序
// node集成了 http服务 所以我们只需要导入库
var http = require('http');
// 创建一个服务器
http.createServer(function(req, res) {
// 发送响应头
res.writeHead(200, { 'Content-Type': 'text/plain' });
// 发送响应数据
res.end('Hello World!');
}).listen(8080); // 监听8080端口 其实这个操作也是为其绑定端口
console.log('Server running at http://127.0.0.1:8080/'); // 输出提示信息
二、npm的使用
npm就相对于python的pip 就是进行下载安装拓展库的 非常好用
1 npm -v 查看当前的nmp的版本
2 下载 :1、本地安装 :
本地安装很有局限 就是我如果在这个 VS 编辑器的终端安装的这个只能作用于我当前的文件夹
2、全局安装 nmp install -g 全局就用解决上边的问题
3、 查看安装的库 nmp list
4 、删除库 nmp uninstall 库名
5、更新 nmp update 库名
三、node.js的REPL
读 行 印 环 (R 读写 E执行 P 打印 L 循坏)
重点 : _ 变量 _ 可以让你获取上个变量执行的结果
四、非阻塞性
阻塞性展示
var fs = require('fs'); //调用文件操作库
var data = fs.readFileSync('1.txt'); //读取文件内容
console.log(data.toString());
console.log('程序执行完毕'); // 提示信息
我们发现没有执行读取文件的内容 是因为单线程无法实现双管齐下
非阻塞性展示
fs.readFile('1.txt', function(err, data) { //使用 readFile 方法读取文件内容,并将读取结果作为参数传递给回调函数
if (err) {
console.log(err);
} else {
console.log(data.toString());
}
});
console.log('程序执行完毕'); // 提示信息
第一个没有成功的原因 就是程序的等待 程序等待文件内容被提取再进行
第二个是有回调函数才使得 先执行不需要时间的程序 最后再执行它
// 当多个异步操作需要按顺序执行时,回调函数会导致代码嵌套,使得代码难以阅读和维护。 这个就是回调地狱 所以现实中都使用
// Promises:Promises 是一种新的异步编程模式,它允许你以链式的方式处理异步操作,避免了回调地狱。
// async/await:基于 Promises,async/await 提供了一种更接近同步代码风格的异步编程方式,使得异步代码更易于理解和维护。
// 第一种模式 使用 await 英语翻译是等一下
var fs = require('fs').promises; //promise模式
async function readFile() {
try {
let data = await fs.readFile('1.txt'); //使用 readFile 方法读取文件内容,并将读取结果作为参数传递给回调函数
let str = console.log(data.toString()); //打印文件内容
} catch (err) {
console.log(err);
}
}
但是这种模式还是太吃操作了
还是直接使用异步then比较好用
fs.readFile('1.txt').then(data => { //使用 readFile 方法读取文件内容,并将读取结果作为参数传递给回调函数
console.log(data.toString());
}).then(() => {
console.log('程序执行完毕'); // 提示信息
}).catch(err => {
console.log(err);
});
文件系统的操作和安全问题
var fs = require('fs').promises; //异步执行 读取fs文件系统
fs.readFile('1.txt').then(date => { //读取1.txt文件 并把返回值 data 赋值给date变量 输出
console.log(date.toString());
}).then(() => { //读取完成后 输出提示信息
console.log("程序执行完毕");
}).catch(err => { //如果出错 输出错误信息
console.log(err);
});
原始的写法
fs.readFile('1.txt', function(data, err) {
if (err) {
console.log(err);
} else {
console.log(data.toString());
}
});
console.log("程序执行完毕");
express框架
作用 集成的web应用框架 可以快速搭建web服务器
先进行安装 nmp install express -g
使用:
先导入模块
app.get('/file', function(req, res) { //web服务器 监听根目录 请求返还的定义 /是路由
filename = req.query.filename; //获取客户端请求的filename参数
fs.readFile(filename, function(data, err) {
if (err) {
console.log(err);
} else {
console.log(data.toString());
res.send(data.toString()); //把读取的文件内容 发送给客户端 显示在浏览器上
}
});
});
var server = app.listen(3000, function() { // 配置服务器的端口
var host = server.address().address
var port = server.address().port
console.log("应用实例,访问地址为 http://%s:%s", host, port)
});
RCE操作
const child_process = require('child_process'); //引入child_process模块
var express = require('express');
var app = express();
var shell = require('shelljs'); //引入shelljs模块 shelljs可以执行shell命令
shell.exec('calc')
app.get('/rce', function(req, res) {
const cmd = req.query.cmd;
child_process.exec(cmd);
})
//命令执行
// child_process.exec('calc');
// child_process.spawnSync('calc');
//代码执行
// eval('child_process.exec(\'calc\');');
var server = app.listen(8081, function() {
var host = server.address().address
var port = server.address().port
console.log("应用实例,访问地址为 http://%s:%s", host, port)
})
SQl数据库操作
var mysql = require('mysql'); //引入mysql模块
var express = require('express');
var app = express();
var connection = mysql.createConnection({
host: 'localhost', //数据库地址
user: 'root', //用户名
password: '123456', //密码
database: 'demo01' //数据库名
});
connection.connect(); //连接数据库
app.get("/sql", function(req, res) {
const id = req.query.id; //获取查询参数
const sql = 'select * from admin where id=' + id;
connection.query(sql, function(err, result) {
if (err) {
console.log('[SELECT ERROR] - ', err.message);
return;
}
console.log(result);
res.send(result); //返回查询结果到浏览器
});
})
var server = app.listen(8082, function() {
var host = server.address().address
var port = server.address().port
console.log("应用实例,访问地址为 http://%s:%s", host, port)
})
原型链污染
但是每个对象都有一个初始值 __proto__ 我们可以通过 修改初始值从而使 空对象继承 而被污染