node.js学习笔记

node.js学习笔记

    • 1.nodejs简介
    • 2.node环境的安装
        • 搭建一个服务器
    • 3.模块化规范(重点)
    • 4.ES6的模块化
    • 5.fs模块
    • 6.path
    • 7.路由
    • 8.form提交数据
    • 9.querystring
    • 10.ajax
    • 11.NPM
      • nodemon自动重启工具
    • 12.express
    • 13.跨域访问
    • 14.node接收前端请求参数
      • get
      • post
        • 1.传json对象
        • 2.传urlencoded
    • 15.数据库
      • 15.1mongodb
      • 15.2nodejs连接mongo
    • 16.token

1.nodejs简介

nodeJS就是ECMAScirpt。在原来学习的ES的基础上增加了后端相关的API, 如:HTTP,fs,URL等等。让JavaScript还可以做后端的开发,即一门语言搞定前后端,即全栈

nodejs是一个平台,包含了js的编译引擎(谷歌v8JS引擎) + 大量稀奇古怪的API(60万)

原生的js只能实现网页交互,如dom,bom操作,发送ajax,不能实现如读写文件,不能调用window自带API

nodejs可以用来搭建服务器

2.node环境的安装

双击安装软件—>打开控制台输入

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,再次执行

3.模块化规范(重点)

问题?

没有了HTML文件作为桥梁,js文件将如何实现互相引用?

nodejs中,js文件相互引入的规则称为Commonjs

nodejs淡化类的概念,所有的类通过模块思想代替,模块的本质就是js文件

模块的分类:

  • 系统的模块 http fs url
  • 自定义的模块(你自己写的js文件)
  • 第三方模块(通过npm下载)

CommonJS 导入和导出的规则:

导入

let 对象 = require(模块名称);

导出

a.

exports.自定义属性1 =1

exports.自定义属性2 =2

b.

module.exports = {

        key1:value1,

        key2:value2...

 }

注意事项:

  1. 平级目录也要添加./

  2. .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();

4.ES6的模块化

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>

5.fs模块

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", () => { });



6.path

文件路径模块,可以实现文件路径的解析以及拼接

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());
    }
});

7.路由

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>

8.form提交数据

前端文件

<!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);

9.querystring

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);

10.ajax

前端代码

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);

11.NPM

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所在目录

nodemon自动重启工具

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");

12.express

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");
});

13.跨域访问

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"));

14.node接收前端请求参数

get

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
    });
});

post

1.传json对象

怎么传

通过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

2.传urlencoded

怎么发

通过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
    });
});

15.数据库

存储数据的一个软件,该软件对数据的增删查改提供了大量优质的算法,

极大提高数据操作效率

  • 关系型数据库:mysql

  • 非关系型数据库:Mongodb

15.1mongodb

安装,无脑双击下一步

控制台输入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

15.2nodejs连接mongo

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("读取失败");
           }
       });
   }
});

16.token

上下文,产生条件

http是无状态协议,每次登录完之后,服务器是没有记忆能力的,

下一次在访问需要权限的页面时,要重新登录

token的本质就是一个加密字符串

​ 如何使用token

​ 思想

​ 在服务端不需要存储用户的登录记录,全部发给客户端**由客户端自己存(**cookie,localStorage)

​ 1、客户端使用用户名跟密码请求登录(前端)

​ 2、服务端收到请求,去验证用户名与密码 (后端)

​ 3、验证成功后,服务端会签发(产生)一个 Token(加了密的字符串),再把这个 Token 发送给客户端(后端)

​ 4、客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里(前端)

​ 5、客户端每次向服务端请求资源的时候需要带着服务端签发的 Token(前端)

​ 6、服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据

你可能感兴趣的:(前端,node.js,javascript,前端)