nodeJS就是ECMAScirpt。在原来学习的ES的基础上增加了后端相关的API, 如:HTTP,fs,URL等等。让JavaScript还可以做后端的开发,即一门语言搞定前后端,即全栈
nodejs是一个平台,包含了js的编译引擎(谷歌v8JS引擎) + 大量稀奇古怪的API(60万)
原生的js只能实现网页交互,如dom,bom操作,发送ajax,不能实现如读写文件,不能调用window自带API
nodejs可以用来搭建服务器
双击安装软件—>打开控制台输入
node -v(启动服务器)
node是一个命令
node js文件名 —> 编译且运行该js文件
node hellonode.js
如何切换控制台目录—>在文件所在目录地址中输入cmd
// const http = new http();
const http = require('http');
// 创建一个服务器对象
const server = http.createServer((req, res) => {
// 设置乱码格式
res.writeHead(200, { "content-type": "text/html;charset=utf-8" });
// res.end(响应给用户的内容);
res.end("慧会");
// res.end(`
//
//
// 666
//
// 2
// 3
// 4
// 5
//
// `)
})
// 添加端口号
// 端口号的取值范围是0~65535
// 建议自定义端口号超过8080
server.listen(8888);
// 运行顺序:
// 1.先在文件根目录下启动服务器运行该文件
// 2.然后在浏览器端输入:ip地址+端口号
// 3.再次启动服务器是Ctrl+c退出服务器+enter,再次执行
问题?
没有了HTML文件作为桥梁,js文件将如何实现互相引用?
nodejs中,js文件相互引入的规则称为Commonjs
nodejs淡化类的概念,所有的类通过模块思想代替,模块的本质就是js文件
模块的分类:
CommonJS 导入和导出的规则:
导入
let 对象 = require(模块名称);
导出
a.
exports.自定义属性1 = 值1
exports.自定义属性2 = 值2
b.
module.exports = {
key1:value1,
key2:value2...
}
注意事项:
平级目录也要添加./
.js后缀在导入时,是可以省略的
node_modules文件夹存放的文件夹可以直接被导入,
导入的是该文件夹index.js文件
文件3.a.js
// 导出:也称为暴露,被暴露的属性或者方法可以理解为是公有
// 没有暴露的属性和方法是私有
// a. expotrs
// let a = 123;
// let b = 999;
// function fun() {
// console.log("fun");
// }
// exports.a = a;
// exports.fun = fun;
// ----------------------------
// b.
let a = 123;
let b = 999;
let c = 888;
function fun(){
console.log("fun");
}
// 对外暴露,一个对象既可以作为key也可作为value
module.exports = {
a,
b,
fun
}
文件3.b.js
const myModule = require("./3.a");
// console.log(myModule.a, myModule.b);
// myModule.fun();
module.exports = {
myModule,
c: 678,
fun1: function () {
console.log("fun1");
},
fun2: function () {
console.log("fun2");
}
}
let d = 999;
文件3.c.js
const myModuleC = require("./3.b");
// console.log(myModuleC.myModule.a);
// console.log(myModuleC.myModule.b);
// console.log(myModuleC.c);
// myModuleC.myModule.fun();
// myModuleC.fun1();
// myModuleC.fun2();
// node_modules文件夹存放的文件夹可以直接被导入,
// 导入的是该文件夹index.js文件
const myTest = require("myTest");
console.log(myTest.aa);
myTest.fun();
ES6的模块化是前端js文件导入
导入:
// 导出
// a.
export let a = 123;
export function fun() {
console.log("hello new world");
}
let b = 999;
// b.
// let a = 666;
// function fun() {
// console.log("我爱学习");
// }
// export default {
// a,
// fun
// }
导出
// 导入
// a.
import { a, fun } from "./1.es6模块化_a.js";
console.log(a);
fun();
// b.
// import myModule from "./1.es6模块化_a.js";
// console.log(myModule.a);
// myModule.fun();
使用
<script src="1.es6模块化_b.js" type="module"></script>
file system 包含文件读写的相关操作
const fs = require('fs');
// 同步读文件
// let str = fs.readFileSync("文件路径");
// let str = fs.readFileSync("1.es6模块化_a.js");
// 将字符的二进制编码改为字符串内容
// console.log(str.toString());
// 异步的读文件
// fs.readFile("文件路径",(err,data)=>{})
// fs.readFile("123.txt", (err, data) => {
// // if (err) {
// // console.log("文件路径不正确");
// // } else {
// // console.log(data.toString());
// // }
// // 用异常处理机制代替if...else
// try {
// console.log(data.toString());
// } catch (err) {
// console.log("文件路径不正确");
// }
// });
// 异步的写
// fs.writeFile("文件路径", "写入的内容", { flag: "w|a" }, () => {
// // w为覆盖,a为追加
// });
// fs.writeFile("123.txt", "嘿嘿嘿", { flag: "a" }, () => {
// console.log("写入成功");
// });
// fs.writeFile("666.txt", "我就是没有", () => { });
// 注意事项:如果源文件存在,则删除源文件,重新创建且覆盖
// 如果文件不存在,则创建新文件
// 创建一个文件夹
// fs.mkdir("heihie", () => { });
// 删除一个文件夹
// fs.rmdir("heihie", () => { });
// 删除文件
fs.unlink("666.txt", () => { });
文件路径模块,可以实现文件路径的解析以及拼接
const path = require('path');
// let str1 = path.parse("F:/htmlTest/第二阶段/后四周/第三周/day32");
// console.log(str1);
const fs = require('fs');
// let str2 = fs.readFile("../123.txt", (err, data) => {
// if (err) {
// console.log("失败");
// } else {
// console.log(data.toString());
// }
// });
// 当前文件所在的文件夹的绝对目录
// console.log(__dirname);
// // 当前文件所在的绝对目录
// console.log(__filename);
// // resolve是用来拼接路径的函数
let path1 = path.resolve(__dirname, "../", "123.txt");
console.log(path1);
// 路径中的../错误
// let str2 = fs.readFile(__dirname+"../"+"123.txt",(err,data)=>{
let str2 = fs.readFile(path1, (err, data) => {
if (err) {
console.log("失败");
} else {
console.log(data.toString());
}
});
url: http:// ip地址 + 端口号 + 路由参数 + 请求参数
后端文件
const http = require('http');
const fs = require('fs');
// 创建一个服务器对象
http.createServer((req, res) => {
// 设置乱码格式
res.writeHead(200, { "content-type": "text/html;charset=utf-8" });
// req.url 获取路由参数
// console.log(req.url);
// 响应给用户的内容
// res.end("4.reg.html");
if (req.url == '/login') {
res.end("登录页面");
} else if (req.url == '/reg') {
// res.end("注册页面");
fs.readFile(__dirname + "/4.reg.html", (err, data) => {
try {
res.end(data);
} catch (err) {
res.end("404");
}
});
} else if (req.url == '/admin') {
res.end("后台管理页面");
}
}).listen(8888);
前端文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
用户名:<input type="text" name="" id=""><br>
密码 :<input type="text" name="" id=""><br>
<button>注册</button>
</body>
</html>
前端文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form action="http://127.0.0.1:8888/reg">
姓名:<input type="text" name="userName"><br>
<select name="list" id="">
<option value="已婚">已婚</option>
<option value="未婚">未婚</option>
<option value="海王">海王</option>
</select>
<input type="submit" value="提交">
</form>
</body>
</html>
后端文件
const http = require('http');
const url = require('url');
http.createServer((req, res) => {
console.log(req.url);
// url.parse(req.url).pathname:返回不带请求参数的路由
let pathname = url.parse(req.url).pathname;
console.log(pathname);
// console.log(url.parse(req.url));
if (pathname == "/reg") {
console.log("heihei");
let { userName, list } = url.parse(req.url, true).query;
console.log(userName, list);
res.end("q12343");
}
}).listen(8888);
const querystring = require('querystring');
// 将键值对转为json对象
let qs = querystring.parse(`key=value&key2=value2`);
console.log(qs.key, qs.key2);
// 将json对象转为键值对
let str = querystring.stringify(qs);
console.log(str);
前端代码
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Documenttitle>
head>
<body>
姓名:<input type="text"><br>
<select>
<option value="已婚">已婚option>
<option value="未婚">未婚option>
<option value="海王">海王option>
select>
<input type="submit" value="提交">
body>
html>
<script>
let oInput = document.querySelectorAll("input");
let oSelect = document.querySelector("select");
oInput[1].onclick = function () {
let xhr = new XMLHttpRequest();
xhr.open("get", `http://127.0.0.1:8888/reg?userName=${oInput[0].value}&list=${oSelect.value}`, true);
xhr.send();
xhr.onload = function () {
fun(xhr.responseText);
}
}
function fun(resText) {
console.log(resText);
}
script>
后端代码
const http = require('http');
const url = require('url');
const fs = require('fs');
http.createServer((req,res)=>{
let pathname = url.parse(req.url).pathname;
if(pathname == '/reg'){
let {userName,list} = url.parse(req.url,true).query;
res.end(userName + "," + list);
}else if(pathname == '/ajax'){
fs.readFile(__dirname+"/7.ajax.html",(err,data)=>{
try{
res.end(data);
}catch(err){
res.end("404");
}
});
}
}).listen(8888);
NPM:包管理工具,安装node平台时自带的软件
npm -v 作用:可以下载模板
前置条件:使用npm时,请在项目根目录下创建package.json文件 —>用npm init命令 + enter yes
下载模块的命令
npm install 模块名称 -S | -D | -g
-S : 生产依赖(项目跑起来需要的模块)
-D :开发依赖(项目编写的过程中需要的模块)
-g :全局
当代码拷贝在一个新的电脑上时,可以用 npm i 命令下载所有依赖模块
jquery的特点是找dom对象
使用npm时,要先使用nmp init命令在项目根目录下创建package.json文件,如果没有该文件夹则在拷代码的时候将需要的第三方文件都要拷上
如果一个软件安装时没有配置全局环境变量
此电脑—>属性—>高级系统设置—>高级—>环境变量—>系统变量—>path—>新建—>复制exe所在目录
npm i nodemon -g 下载自动重启工具
下载后用 nodemon + 文件名启动
保存(ctrl+s)便执行js文件
const sd = require('silly-datetime');
let str = sd.format(new Date(), "YYYY-MM-DD HH:mm:ss");
console.log(str);
console.log("hellow world1");
express:node封装搭建服务器的框架
使用步骤:
1.通过npm在项目目录下下载该模块
导入express模块
2.const express = require('express');
这一步就等于原生的createSever,创建了一个服务器对象app
3.const app = express();
设置ip及端口号
app.listen(端口,ip,回调函数);
通过路由的方式访问
app.get('路由参数1',(req,res)=>{ });
app.post('路由参数2',(req,res)=>{ });
// 导入express模块
const express = require('express');
// 这一步就等价于原生的createServer,创建了一个服务器对象app
const app = express();
// 设置IP及端口号
// app.listen(端口,ip,回调函数);
app.listen(8888, "127.0.0.1", () => {
console.log("服务器启动成功");
});
app.get("/reg", (req, res) => {
res.end("hahhahah");
});
app.get("/login", (req, res) => {
res.end("yinyinyin");
});
app.use(容器,处理不同的操作)
express.static(静态资源文件夹):该目录下的所有文件可以当做服务器的文件
app.use(express.static(__dirname + "/weibo"));
// 导入express模块
const express = require('express');
// 这一步就等价于原生的createServer,创建了一个服务器对象app
const app = express();
// 设置IP及端口号
// app.listen(端口,ip,回调函数);
app.listen(8888, "127.0.0.1", () => {
console.log("服务器启动成功");
});
// app.use(容器,处理不同的操作)
// express.static(静态资源文件夹):该目录下的所有文件可以当做服务器的文件
app.use(express.static(__dirname + "/weibo"));
1.query
如何传?
http://127.0.0.1:8888/sum?a=1&b=2
如何接收?
req.query {a:'1',b:'2'}
2.params
如何传?
http://127.0.0.1:8888/3/4
如何接收?
req.params
html文件
<script>
let xhr = new XMLHttpRequest();
// query传参
xhr.open("get", "http://127.0.0.1:8888/reg?userName=laowang&userPwd=6666", true);
// params
// xhr.open("get", "http://127.0.0.1:8888/reg/laoliu/8888", true);
xhr.send();
xhr.onload = function () {
fun(xhr.responseText);
}
function fun(resText) {
console.log(resText);
}
script>
后端文件
const express = require('express');
const app = express();
app.listen(8888, "127.0.0.1", () => {
console.log("get传参");
})
app.use(express.static(__dirname));
app.get("/reg", (req, res) => {
let { userName, userPwd } = req.query;
// req请求参数
// res返回参数
res.json({
userName,
userPwd
});
});
app.get("/reg/:userName/:userPwd", (req, res) => {
let { userName, userPwd } = req.params;
res.json({
userName,
userPwd
});
});
怎么传
通过json传参
xhr.setRequestHeader("content-type", "application/json");
必须要以字符串的形式发送
xhr.send(JSON.stringify({
"userName":"laoliu",
"userPwd":123456
}));
怎么收
const bodyParser = require("body-parser");
接收json对象
app.use(bodyParser.json());
接收post过来的json数据
req.body
怎么发
通过urlencoded 传参
xhr.setRequestHeader("content-type", "application/x-www-form-urlencoded");
xhr.send("userName=laowu&userPwd=66666");
xhr.onload = function(){
fun(xhr.responseText);
}
怎么收
const bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({
extended:false
}));
req.body
前端文件
<script>
let xhr = new XMLHttpRequest();
xhr.open("post", "http://127.0.0.1:8888/reg", true);
// 通过json传参
xhr.setRequestHeader("content-type", "application/json");
// 必须要以字符串的形式发送
xhr.send(JSON.stringify({
"userName": "laoliu",
"userPwd": 123456
}));
// 通过urlencoded传参
// xhr.setRequestHeader("content-type", "application/x-www-form-urlencoded");
// xhr.send("userName=laowu&userPwd=66666");
xhr.onload = function () {
fun(xhr.responseText);
}
function fun(resText) {
console.log(resText);
}
script>
后端文件
const express = require('express');
const app = express();
app.listen(8888, "127.0.0.1", () => {
console.log("post传参");
})
app.use(express.static(__dirname));
// post传参需要通过中间件来接收
// 创建中间件
const bodyParser = require("body-parser");
const { urlencoded } = require('express');
// 接收json对象
app.use(bodyParser.json());//接收post过来的json数据
// 接收urlencoded参数
app.use(bodyParser / urlencoded({
extended: false
}));
app.post("/reg", (req, res) => {
console.log(req.body);
let { userName, userPwd } = req.body;
res.json({
userName,
userPwd
});
});
存储数据的一个软件,该软件对数据的增删查改提供了大量优质的算法,
极大提高数据操作效率
关系型数据库:mysql
非关系型数据库:Mongodb
安装,无脑双击下一步
控制台输入mongo
库------>集合
数据库的操作:
库操作:
显示有多少数据库
查 show dbs
增 切换 use 库名
删库 db.dropDatabase()
显示库中包含的集合
show collections
删除 db.集合.drop()
全部操作都是围绕着集合中数据的增删查改
增
db.集合.insert({name:“laowang”,“age”:18}) //添加一条
db.集合.insert([{userName:“杨浩浩”},{userName:“张毅清”}]):添加多条记录
批量导入一些数据:不要在mongo环境下执行
mongoimport --db score --collection userScore --file D:\1907\Lession04\mongodb\userScore
--db:指定数据库
--collection:指定集合
--file:指定导入的文件。
--drop:将原来的内容覆盖掉。
查
db.集合.find();查看集合当中的文档列表
db.student.count():是查看当前集合的文档总条数
db.student.find({sex:“男”}).count():获得符合条件的文档数量
db.student.find({userName:“张三”}):精确查找:userName是张三
删除
db.student.deleteOne({userName:“王五”}) 删除userName为王五的对象
改
db.student.update({userName:“杨昊”},{$set:{age:543}})
第一个参数是条件,第二个参数是修改的内容。
将名字为杨昊,年龄更改为543
1.下载mongodb模块
npm i mongodb -S
2.引入模块
const mongodb = require(‘mongodb’);
3.创建连接对象
const mongoClient = mongodb.MongoClient;
// 引入模块
const mongodb = require('mongodb');
// 将MongoClient赋值给mongoCilent
const mongoClient = mongodb.MongoClient;
mongoClient.connect("mongodb://127.0.0.1:27017", (err, client) => {
if (err) {
console.log("连接失败");
} else {
console.log("连接成功");
// 选择库
// const db = client.db("2213");
//增
//插入一条数据
// db.collection(集合名).insertOne({ userName: "刘德华"});
// db.collection("userList").insertOne({ userName: "刘德华" });
// db.collection("data").insertOne({"id":9527,"userName":"fengfeng","userPwd":123456});
//删
// db.collection("userList").deleteOne({ userName: "刘德华" }, (err, res) => {
// if (!err) {
// console.log("删除成功:" + res);
// } else {
// console.log("读取失败");
// }
// });
//查
// db.collection("userList").find({ userName: "刘德华" }).toArray((err, result) => {
// if (!err) {
// console.log(result);
// for (let i = 0; i < result.length; i++) {
// console.log(result[i].userName);
// }
// } else {
// console.log("读取失败");
// }
// });
//改
db.collection("userList").updateOne({ userName: "刘德华" }, { $set: { userName: "黎明" } }, (err, res) => {
if (!err) {
console.log("修改成功:res");
} else {
console.log("读取失败");
}
});
}
});
上下文,产生条件
http是无状态协议,每次登录完之后,服务器是没有记忆能力的,
下一次在访问需要权限的页面时,要重新登录
token的本质就是一个加密字符串
如何使用token
思想
在服务端不需要存储用户的登录记录,全部发给客户端**由客户端自己存(**cookie,localStorage)
1、客户端使用用户名跟密码请求登录(前端)
2、服务端收到请求,去验证用户名与密码 (后端)
3、验证成功后,服务端会签发(产生)一个 Token(加了密的字符串),再把这个 Token 发送给客户端(后端)
4、客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里(前端)
5、客户端每次向服务端请求资源的时候需要带着服务端签发的 Token(前端)
6、服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据