什么是node.js ?
-
Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境 v8解析js是最快的
-
nodejs是让js运行在服务器端
nodejs里面的API大多数都是异步 -
服务器端的js和浏览器端的js有什么区别?
客户端的js三个组成部分 :
DOM 文档对象模型 js操作网页内容的一套API
BOM 浏览器对象模型 js操作浏览器页面的一套API
ECMAScript 一套js语法的规范 for
服务端的js 只有ECMAScript 独立于浏览器运行的
优势 :
- 了解浏览器端和服务器端的交互过程 可以缩短开发周期
- 出现bug 可以快速定位是前端问题还是后端问题
- nodejs和其它后端语言拥有一样的功能 可以做数据库的增删改善 爬虫 读写文件…
1. 怎么下载使用node.js
第一步 :
进入 node.js 官网
第二步 :
下载好后 在底部搜索框输入 cmd, 查看下好后的版本指令 : node -v npm -v
退出node环境 使用后ctrl + c (按两次)
出现后说明已安装完成 , node 会根据安装的文件位置,自动配置 path 环境
2. 读取和写入文件
读取文件 :
导入模块 require(“模块名”) 模块名是nodejs内部规定死的 不能动
左边保存的变量可以修改 但是通常情况下和模块名保持一致
const fs = require('fs');
参数1 : 需要被读取的文件的路径
参数2 : 可选参数 我们这里给的是编码格式
参数3 : 回调函数 里面有连个参数 err 表示读取失败时返回的信息 data是读取到的文件信息
fs.readFile("./novels/02.txt","utf-8", (err, data) => {
// console.log(err);
// console.log(data);
if(!err) {
console.log(data);
} else {
console.log("文件读取失败");
}
})
写文件 :
导入fs模块
const fs = require("fs");
参数1 : 存入信息或者数据的文件路径
参数2 : 需要写入的数据
参数3 : 回调函数
fs.writeFile("./novels/02.txt", "开心", err => {
// console.log(err);
if(!err) {
console.log('写入成功');
} else {
console.log("写入失败");
}
})
3. http url path 三个模块
导入模块
const http = require("http");
创建http服务
const server = http.createServer((request, response) => {
console.log(1111);
// console.log(request);
// 请求路径
console.log(request.url);
// 请求方式
console.log(request.method);
// 1. 设置响应头 服务器为了告诉浏览器 我返回给你的数据 你用utf-8来解析
response.setHeader("content-type", "text/html;charset=utf-8")
// response.end("how are you?")
response.end("刚好遇见你")
// 开启服务器
server.listen("80", "127.0.0.1", () => {
console.log("start");
})
})
注意 :
地址可以省略 但是端口号不行 地址不填 默认是127.0.0.1
server.listen("8080", () => {
console.log("start");
}
4. node路径问题
const fs = require("fs");
fs.readFile(__dirname + "\\novels\\01.txt", "utf-8", (err, data) => {
console.log(data);
})
console.log(__dirname + "\\novels\\01.txt");
console.log(__filename);
nodejs里面的相对路径 是相对于当前运行node命令的终端所处相对路径
为了保证在任何地方打开终端 都可以运行 那么我们的路径使用绝对路径
解决办法 : __dirname
__dirname 是当前文件所在的文件的绝对路径
__filename 是当前文件的绝对路径
4.1 nodejs路径模块
// 导入模块
const path = require("path");
const fs = require("fs");
const pathName = path.join("name", "info", "assets", "index.html");
console.log(pathName);
// 在使用到路径的地方 使用绝对路径
const txtPath = path.join(__dirname, "novels", "01.txt");
console.log(txtPath);
// 读取文件
fs.readFile(txtPath, "utf-8", (err, data) => {
if(!err) {
console.log(data);
} else {
console.log(err);
}
})
4.2 模拟web服务器
// 导入模块
const http = require("http");
const fs = require("fs");
const path = require("path");
// 创建服务器对象
const server = http.createServer((request, response) => {
const reqUrl = request.url;
// 读取index.html页面的额内容
fs.readFile(path.join(__dirname, "www", reqUrl), (err, data) => {
if(!err) {
response.end(data);
} else {
response.end(
`<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL ${reqUrl} was not found on this server.</p>
</body></html>`)
}
})
})
server.listen("8090", () => {
console.log("start");
})
5. get和Post请求
// 导入http模块
const http = require("http");
const url = require("url");
const querystring = require("querystring")
// 创建服务器对象
const server = http.createServer((request, response) => {
console.log(request.method);
response.end(request.method);
console.log(request.url);
const reqMed = request.method;
if(reqMed === "GET") {
console.log(request.url);
const reqUrl = request.url;
// 引入url模块 调用parse来解析url
console.log(url.parse(reqUrl, true));
const getdata = url.parse(reqUrl, true).query;
console.log(getdata);
console.log(getdata.name);
console.log(getdata.skill);
} else if(reqMed === "POST") {
var postStr = "";
request.on("data", (data) => {
postStr += data;
})
// end事件表示数据传输完毕
// end事件 没有参数
request.on("end", () => {
// post请求传递的数据不是url 只是单纯的key=value&key1=value1这种类型的字符
// 我们可以直接使用querystring.parse来解析
const postData = querystring.parse(postStr);
console.log(postData);
})
}
})
// 开启服务器
server.listen("8848", () => {
console.log("start");
})
6. 爬虫 crawler
1
2.
3.
步骤 :
- 导入fs模块
var fs = require("fs");
- 创建爬虫对象
var c = new Crawler({
// 最大的连接数
maxConnections : 10,
// This will be called for each crawled page
// 爬完一个数据 会触发的事件
callback : function (error, res, done) {
if(error){
console.log(error);
}else{
var $ = res.$;
console.log($("title").text());
}
done();
}
});
- 爬取的网址 可以是单个, 也可以是多个
// Queue just one URL, with default callback
c.queue('http://www.amazon.com');
// Queue a list of URLs
c.queue(['http://www.google.com/','http://www.yahoo.com']);
7. express静态资源托管
- 导入express模块
const express = require("express");
- 创建服务器
const app = express();
- 静态资源托管
app.use(express.static('public'));
app.use(express.static('static'));
- 开启监听
app.listen(4399);
7.1 路由的使用
// 导入express模块
const express = require("express");
const querystring = require("querystring");
// 创建服务器
const app = express();
// get请求数据 express已经封装好了解析的方法 点query出来的就已经是对象
app.get("/search", (req,res) => {
console.log(req);
console.log(req.query);
res.send("/search");
})
app.post("/add", (req, res) => {
// 使用get的方式获取参数 获取不到 因为他不是在url传数据
// console.log(req);
// console.log(req.query);
var str = "";
req.on("data", data => {
str += data;
})
req.on("end", () => {
console.log(str);
var data = querystring.parse(str);
console.log(data);
})
res.send("/add");
})
// 开启监听
app.listen(8848);
7.2 中间件
// 导入express模块
const express = require("express");
// 导入bodyParser
const bodyParser = require("body-parser");
// 创建服务器
const app = express();
// 注册中间件
app.use(bodyParser.urlencoded({ extended: false }))
// 写一个post请求的路由
app.post("/add", (req, res) => {
// console.log(req);
console.log(req.body);
res.send("/add");
})
// 监听服务器
app.listen(8090);
8. Cookie
setcookie的三个参数
参数1 保存的键
参数2 保存的值
参数3 保存的时效 设置的过期的事件
setcookie("userName", "鹿晗", time()+60*60);
setcookie("password", "123456", time() + 20);
//cookie可以设置修改
setcookie("password", "888888", time() + 20);
Cookie的删除 :
1. 在浏览器开发者工具里面 删除选中的 或者删除全部
2. 设置过期时间 时间一到 就自动删除
3. 直接删除的话 可以设置一个过期时间
setcookie("password", "123456", time() - 20);
使用的注意点
cookie只能存储字符串 不能存储其他数据类型 否则就会报错
setcookie("userInfo", {name : '刘德华'}, time() + 20);
9. mongodb 基本增删改查
1.导入mongodb模块 并且创建一个客户端对象
const MongoClient = require('mongodb').MongoClient;
2.数据库地址
const url = 'mongodb://localhost:27017';
声明数据库名
const dbName = 'myproject';
调用连接数据库的方法
MongoClient.connect(url, function(err, client) {
console.log("连接成功");
const db = client.db(dbName);
// 选择使用的集合
const collection = db.collection('documents');
// 删除数据
collection.deleteOne({name : "红烧狮子头"}, (err, result) => {
console.log(result);
// 关闭数据库
client.close();
})
// 修改数据
// collection.updateOne({name : "鱼香肉丝"}, {$set : {name : "鱼香肉片"}}, (err,result) => {
// console.log(result);
// // 关闭数据库
// client.close();
// })
// 查询数据
// collection.find({name : "鱼香肉丝"}).toArray(function(err, docs) {
// console.log("Found the following records");
// console.log(docs)
// // 关闭数据库连接
// client.close();
// });
// 插入单条数据
// collection.insertOne(
// {
// name : "土豆丝炒洋芋",
// color : "yellow",
// friend : "马铃薯炒土豆"
// }
// , function(err, result) {
// console.log("连接成功");
// console.log(result);
// // 关闭数据库连接
// client.close();
// });
// 插入多条数据
// collection.insertMany([
// {
// name : "鱼香肉丝",
// color : "棕色"
// },
// {
// name : "黄金蛋炒饭",
// color : "金黄色"
// },
// {
// name : "红烧狮子头",
// color : "红棕色"
// }
// ], function(err, result) {
// console.log("连接成功");
// console.log(result);
// // 关闭数据库连接
// client.close();
// });
- 封装 mongodb模块:
// 导入mongodb模块 并且创建一个客户端对象
const MongoClient = require('mongodb').MongoClient;
// 数据库地址
const url = 'mongodb://localhost:27017';
// 声明数据库名
const dbName = 'myproject';
// 暴露接口
module.exports = {
find(collectionName, query, callback) {
// 调用连接数据库的方法
MongoClient.connect(url, function (err, client) {
// console.log("连接成功");
const db = client.db(dbName);
// 选择使用的集合
const collection = db.collection(collectionName);
collection.find(query).toArray(function (err, docs) {
// console.log("Found the following records");
// console.log(docs)
callback(docs);
// 关闭数据库连接
client.close();
});
})
},
// 新增
insertOne(collectionName, insertData, callback) {
// 调用连接数据库的方法
MongoClient.connect(url, function (err, client) {
// console.log("连接成功");
const db = client.db(dbName);
// 选择使用的集合
const collection = db.collection(collectionName);
// 插入单条数据
collection.insertOne(insertData, function (err, result) {
// console.log("连接成功");
// console.log(result);
callback(result);
// 关闭数据库连接
client.close();
});
})
},
// 删除
deleteOne(collectionName, query, callback) {
// 调用连接数据库的方法
MongoClient.connect(url, function (err, client) {
// console.log("连接成功");
const db = client.db(dbName);
// 选择使用的集合
const collection = db.collection(collectionName);
// 删除数据
collection.deleteOne(query, (err, result) => {
// console.log(result);
callback(result)
// 关闭数据库
client.close();
})
})
},
// 修改
updateOne(collectionName, query, updateData, callback ) {
// 调用连接数据库的方法
MongoClient.connect(url, function (err, client) {
// console.log("连接成功");
const db = client.db(dbName);
// 选择使用的集合
const collection = db.collection(collectionName);
// 修改数据
collection.updateOne(query, { $set: updateData }, (err, result) => {
// console.log(result);
callback(result)
// 关闭数据库
client.close();
})
})
}
}
- 结合爬虫数据入库
/**
* 1. 下载爬虫模块
* 2. 导入模块
* 3. 写逻辑
*/
var Crawler = require("crawler");
const dbTool = require("./02-封装mongodb模块");
var fs = require('fs');
var cFile = new Crawler({
encoding: null,
jQuery: false,// set false to suppress warning message.
callback: function (err, res, done) {
if (err) {
console.error(err.stack);
} else {
fs.createWriteStream(res.options.filename).write(res.body);
}
done();
}
});
var c = new Crawler({
maxConnections: 10,
// This will be called for each crawled page
callback: function (error, res, done) {
if (error) {
console.log(error);
} else {
var $ = res.$;
// $ is Cheerio by default
$(".wikitable tr").each((index, ele) => {
if (index != 0) {
const heroName = $($(ele).children()[0]).find("a").attr("title");
console.log(heroName);
const heroIcon = $($(ele).children()[0]).find("a>img").attr("data-src");
console.log(heroIcon);
cFile.queue({
uri: heroIcon,
filename: `./imgs/icons/${heroName}.png`
});
// 数据入库
if (heroName !== undefined || heroIcon !== undefined) {
dbTool.insertOne("cqList", {
heroName,
heroIcon
}, (result) => {
console.log(result);
})
}
}
})
}
done();
}
});
// Queue just one URL, with default callback
c.queue('https://cqcn.fandom.com/zh/wiki/%E9%AA%91%E5%A3%AB');
c.queue('https://cqcn.fandom.com/zh/wiki/%E5%89%91%E5%A3%AB');
// 弓手
c.queue('https://cqcn.fandom.com/zh/wiki/%E5%BC%93%E6%89%8B');
c.queue('https://cqcn.fandom.com/zh/wiki/%E7%8C%8E%E4%BA%BA');
c.queue('https://cqcn.fandom.com/zh/wiki/%E6%B3%95%E5%B8%88');
c.queue('https://cqcn.fandom.com/zh/wiki/%E7%A5%AD%E5%8F%B8')