node.js
一,node最基础
一,为什么要学node.js
1.可以让每个人都访问到我们的网页
2.为了学习vue
二,node是什么
一款应该程序,是一个软件,可以运行javascript
三,node的作用
1.开发服务器端应用
2.开发工具类应用
3.开发桌面端应用
四,node的安装
之前安装过
二,命令的相关知识
一,认识命令行工具
windows+r cmd
二,命令的结构
命令的名称+命令的参数1+参数2
三,常用的命令
说明 | 操作 |
---|---|
切换盘符 | C: D: |
切换工作目录 | c'd |
查看目录文件 | dir |
三,node开始
一,第一个node
helloworld.js
console.log('hello world')
在终端运行 node helloworld.js后得到结果
二,node编写时的注意事项
1.不能够使用BOM,DOM的API,可以使用console和定时器API
2.顶级对象为global,可以用globalThis访问顶级对象
四,Buffer
一,什么是Buffer
buffer翻译为缓冲区,是一个类似于Array的对象,用于表示固定长度序列
特点
1.长度固定
2.新能较好,直接对计算机内存进行操作
3.每个元素的大小为1字节(byte)
五,程序运行流程
安装到硬盘,硬盘将数据放入内存,cpu去内存执行指令,再将指令交给I/O设备
程序一般保存在硬盘中,安装过程就是将程序写入硬盘的过程。
六,进程和线程
进程可以理解为运行中的程序,或者一个程序执行的过程。
线程,时一个进程的执行的执行流。
七,fs模块
实现与硬盘的交互
一,写入文件
四个参数 文件名(如果文件不存在,会自动创建),写入的数据,选项设置,回调函数
const fs = require('fs');
fs.writeFile('./qwe.txt','好好学习',err=>{
//如果写入失败erroe的值就是错误对象,如果写入成功err的值就是null
if(err){
console.log('error')
return}
console.log('success')
}
)
二,fs的同步和异步
fs的同步写入
fs.writeFileSync('abc.txt','666)
三,文件的追加写入
const fs = require('fs');
//另一种写法
fs.writeFile('qwe.txt','努力',{flag:'a'} ,error=>{
console.log('真的绝')
})
fs.appendFile('./qwe.txt',',天天向上',err=>{
//如果写入失败erroe的值就是错误对象,如果写入成功err的值就是null
if(err){
console.log('error')
return}
console.log('success')
}
)
四,流式写入
const fs = require('fs')
const ws = fs.createWriteStream('./学习.txt')
ws.write('床前明月光')
ws.write('疑是地上霜')
//关闭流
ws.close()
适合大量写入文件
五,文件写入的场景
例如下载文件,安装软件
在每次需要持久化保存文件的的时候,不一定一定要使用文件写入,但是要向着这个方向去想,问题就不会太大。
六,文件的读取
//引入模块
const fs = require('fs')
//异步读取
// fs.readFile('qwe.txt',(err,data)=>{
// if(err){
// console.log('fail')
// return
// }
// console.log(data.toString())
// })
//同步读取
const wr = fs.readFileSync('./qwe.txt')
console.log(wr.toString())
七,文件读取应用场景
例如电脑开机,程序运行,上传文件
八,fs文件流式读取
const fs = require('fs')
const rs = fs.createReadStream('./素材.mp3')
rs.on('data',chunk =>{
console.log(chunk.length)
})
rs.on('end',()=>{
console.log("读取完成")
})
九,文件重命名和移动
const fs = require('fs')
//调用fs对象的rename方法
// fs.rename('qwe.txt','好好学习.txt',err=>{
// if(err){
// console.log('rename fall')
// }
// console.log('rename success')
// })
// 以上是重命名方法
//下面是文件的移动
fs.rename('qwe.txt','./素材/好好学习.txt',err=>{
if(err){
console.log('rename fall')
}
console.log('rename success')
})
十,文件的删除
const fs = require('fs')
//方法一 unlink方法
fs.unlink('./素材/好好学习.txt',(err) => {
if(err){
console.log('failed')
return;
}
console.log('success')
}
)
//方法二 rm方法 用法和上面一致
十一,fs文件夹操作
const { error } = require('console')
const fs = require('fs')
// 文件夹的一般创建 make
fs.mkdir('./好好学习',(err) => {
if (err) {
console.log('失败');
return;
}
console.log('成功')
})
// 递归创建
// 用法是一致的,不过这个方法要写第二个参数表示允许调用,详细如下
fs.mkdir('./好好学习/b/c',{recursive:true},(err) => {
if (err) {
console.log('失败');
return;
}
console.log('成功')
})
//删除文件夹 remove
fs.rmdir('./好好学习',(err) => {
if (err) {
console.log('失败');
return;
}
console.log('成功')
})
// 递归删除 但是我们不推荐这样删除,这里推荐使用rm方法删除
fs.rmdir('./好好学习/b/c',{recursive:true},(err) => {
if (err) {
console.log('失败');
return;
}
console.log('成功')
})
十二,查看资源状态
文件的状态
const fs = require('fs')
fs.stat('学习.txt',(err,data) => {
if(err){
console.log('faild')
return
}
console.log('success',data)
// data的两个方法检查是否为文件isFile ,检查是否为文件夹isDirectory
})
十三,路径
绝对路径和相对路径
相对路径有一个bug,相对路径的参考目录为工作行的目录
绝对路径‘全局变量’保存的是,所在文件的所在目录的绝对路径
八,path模块
path模块用来操作路径的
API说明 | |
---|---|
path.resolve | 拼接规范的绝对路径 |
path.sep | 获取操作路径分隔符 |
path.parse | 解析路径,获取路径相关信息 |
path.basename | 获取路径基础名称 |
path.dirname | 获取路径目录名 |
path.extname | 获取路径扩展名 |
九,http协议*
双方必须遵守的约定
一,请求报文的结构
二,请求行
组成:请求方法 URL HTTP协议版本号
请求方法:
方法 | 作用 |
---|---|
GET | 主要用于获取数据 |
POST | 主要用于新增数据 |
PUT | 主要用于更新数据 |
DELETE | 主要用于删除数据 |
方法有很多主要是这几个,更主要的是get和post
URL:
定义服务器内的资源
组成:协议名 和 主机名(定位网络上的计算机)和端口号和路径和查询字符串
下面例子:这个例子没有查询字符串
http://127.0.0.1:5500/html/%E6%89%8B%E9%A3%8E%E7%90%B4%E6%A1%88%E4%BE%8B.html
http版本号:
顾名思义不做解释
三,请求头
记录了当前浏览器的一些信息
四,请求体
内容非常灵活可以写任意内容
五,相应报文和相应行和相应头和相应体
十,网络基础知识
一,ip的介绍
32bit二进制数据
标识网络中的设备实现设备之间的通信
IP本身就是一个标识
二,ip分类
个人感觉分类为:公共ip和个人ip,在一个公共场所,通过路由器分配给每个人一个ip和整体的ip,不举例子解释不清楚,分类也不是我说的这么草率。
三,端口
一台计算机有65536个端口,端口用来实现不同计算机的通讯
十一,http模块
一,创建http服务
// 导入http模块
const http = require('http');
//创建服务对象
//request请求报文的封装对象
//response返回报文的对象
const server = http.createServer((request,response) => {
response.end('Hello HTTP Server');//设置响应体
})
//监听端口,启动服务
// listen中的两个参数,一个是端口号,一个是启动服务器后的回调方法
server.listen(9000,() => {
console.log("success")
})
二,注意事项
-
ctrl+c停止服务器
-
当服务器启动后,更新代码,必须重启服务器才能生效
-
响应内容中文乱码解决办法:
response.setHeader('content-type','text/html;charset=utf-8') -
常见的问题端口被占用:1.关闭当前正在运行的监听端口服务2.修改其他端口号
-
http协议默认端口号的80,开发常用的端口号有3000,8080,8090,9000
三,浏览器查看http报文
控制台 network
四,提取http请求报文
想获取请求的数据,需要通过request对象
这里只列举重点,不仅仅只有这几个属性
含义 | 语法 |
---|---|
请求方法 | request.method |
请求路径 | request.url |
url路径 | require('url').parse(request.url).pathname |
url字符串 | require('url').parse(request.url,true).query |
请求头 | request.headers |
// 导入http模块
const http = require('http');
//创建服务对象
//request请求报文的封装对象
//response返回报文的对象
const server = http.createServer((request,response) => {
response.setHeader('content-type','text/html;charset=utf-8')
// 获取请求的方法
console.log(request.method);
// 获取请求的url
console.log(request.url);//这里只包括url中的路径和查询字符串
//获取HTTP协议版本号
console.log(request.httpVersion);//基本上用不到
//获取HTTP的请求头
console.log(request.headers);
response.end('Hello HTTP Server,你好');//设置响应体
})
//监听端口,启动服务
// listen中的两个参数,一个是端口号,一个是启动服务器后的回调方法
server.listen(9000,() => {
console.log("success")
})
我还是不习惯写;啊啊啊啊啊啊
五,提取请求体的内容
// 导入http模块
const http = require('http');
const server = http.createServer((request,response) => {
// 声明一个变量
let body = '';
// 绑定data事件
request.on('data',chunk =>{
body += chunk;
})
// 绑定end事件
request.on('end',()=>{
console.log(body)
response.end('Hello');
})
})
//监听端口,启动服务
// listen中的两个参数,一个是端口号,一个是启动服务器后的回调方法
server.listen(9000,() => {
console.log("success")
})
六,获取路径和查询字符串
// 导入http模块
const http = require('http');
const url = require('url')
const server = http.createServer((request,response) => {
let res = url.parse(request.url,true);
let keyword = res.query.name
let pathname = res.pathname
//获取路径
console.log(res)
console.log(keyword)
// console.log(pathname)
response.end('url')
})
//监听端口,启动服务
// listen中的两个参数,一个是端口号,一个是启动服务器后的回调方法
server.listen(9000,() => {
console.log("success")
})
上面的方法时旧的
下面的是新的
// 导入http模块
const http = require('http');
const url = require('url')
const server = http.createServer((request,response) => {
// 实例化url对象
let url = new URL(request.url,'http://localhost')
console.log(url)
})
//监听端口,启动服务
// listen中的两个参数,一个是端口号,一个是启动服务器后的回调方法
server.listen(9000,() => {
console.log("success")
})
七,响应报文
// 导入http模块
const http = require('http');
const server = http.createServer((request,response) => {
//设置响应状态码
response.statusCode = 201
//设置响应状态描述4
response.statusMessage("666")
//响应头
response.setHeader('Server','Node.js')
//响应体设置
response.write("666")
response.end("666")
})
//监听端口,启动服务
// listen中的两个参数,一个是端口号,一个是启动服务器后的回调方法
server.listen(9000,() => {
console.log("success")
})
八,静态资源和动态资
静态资源是指内容长时间不发生改变的资源,例如图片,视频,CSS
动态资源是指内容经常发生改变的资源
十二,模块化
一,模块化初体验
index1.js
const Study = require('./index2.js')
Study();
index2.js
function Study(){
console.log('我其实不喜欢学习')
}
module.exports = Study;
二,模块暴露数据
两种方法:
function Study(){
console.log('我其实不喜欢学习')
}
function Play(){
console.log('我也不喜欢玩')
}
// 方法一:model.exports = value
module.exports = {
Study,
Play
}
// 方法二:exports.name = value
exports.Study = Study;
exports.Play = Play;
const me = require('./index2.js')
me.Study();
me.Play();
三,导入文件夹
首先先寻找文件夹里package.json里main的值,如果没有则尝试寻找index.json或者index.js文件
不好演示:
const a = require('./model')
console.log(a);
四,导入自定义模块流程
-
将相对路径转换为绝对路径,定位文件夹
-
检测缓存
-
读取文件夹代码
-
包裹为一个函数执行(自己执行的函数),通过arguments.callee.toString()查看自执行函数
-
缓存模块的值
-
返回model.exports的值
这里代码有点离谱,先不看了
十五,express
一,创建express
//导入express模块
import express, { response } from 'express'
// 创建应用对象
const app = new express();
// 创建路由
app.get('/home',(req,res) => {
res.end('hello wds')
});
// 监听接口,启动服务
app.listen(3000,()=>{
console.log('服务器已经启动监听窗口中')
})
二,路由的使用
app.<methods>(path,callback)
//导入express模块
import express, { response } from 'express'
// 创建应用对象
const app = new express();
// 创建路由 注意这里的路径是一个斜线,这里是真正的首页
app.get('/',(req,res) => {
res.end('home')
});
app.post('/login',(req,res)=>{
res.end('login page')
})
app.all('/test',(req,res)=>{
res.end('test')
})
app.all('*',(req,res)=>{
res.end('Not Fond 404')
})
// 监听接口,启动服务
app.listen(3000,()=>{
console.log('服务器已经启动监听窗口中')
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form action="http://localhost:3000/login" method="post">
<button>按钮</button>
</form>
</body>
</html>
三,获取请求报文参数
//导入express模块
import express, { response } from 'express'
// 创建应用对象
const app = new express();
app.get('/home',(req,res)=>{
// 原生操作
console.log(req.method);
console.log(req.url);
console.log(req.httpVersion);
console.log(req.headers);
//express 操作
console.log(req.path);//查询路径
console.log(req.query);//查询字符串
//获取ip
console.log(req.ip);
})
app.listen(3000,()=>{
console.log('服务器已经启动监听窗口中')
})
四,获取 路由参数
//导入express模块
import express, { response } from 'express'
// 创建应用对象
const app = new express();
app.get('/:id.html',(req,res)=>{
// 获取通配符
console.log(req.params.id);
})
app.listen(3000,()=>{
console.log('服务器已经启动监听窗口中')
})
五,路由参数练习
//导入express模块
const express = require('express')
// 创建应用对象
const app = new express();
const {students} = require('./students.json')
app.get('/students/:id.html',(req,res)=>{
let id = req.params.id;
let result = students.find(item=>{
//这里我犯了一个错误,这里的id是字符串,因该类型转换成Number类型
if(item.id === Number(id)){
return true
}
})
if(!result){
res.statusCode = 404;
res.end('Not Fond Student')
return;
}
res.end(`
<!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>
<h2>${result.name}</h2><br>
<h2>${result.age}</h2><br>
<h2>${result.address}</h2>
</body>
</html>
`)
})
app.listen(3000,()=>{
console.log('服务器已经启动监听窗口中')
})
{
"students": [
{
"id":1,
"name": "wds1",
"age": 21,
"address": "山西省太原市"
},
{
"id":2,
"name": "wds2",
"age": 22,
"address": "山西省太原市"
},
{
"id":3,
"name": "wds3",
"age": 23,
"address": "山西省太原市"
},
{
"id":4,
"name": "wds4",
"age": 24,
"address": "山西省太原市"
},
{
"id":5,
"name": "wds5",
"age": 25,
"address": "山西省太原市"
}
]
}
六,一般响应设置
//导入express模块
const express = require('express')
// 创建应用对象
const app = new express();
app.get('/response',(req,res)=>{
// express响应
res.status(500);
res.set('aaa','bbb');
res.send('你好')
// 甚至可以合起来写
res.status(200).set('aaa','bbb').send('这都是ok的');
})
app.listen(3000,()=>{
console.log('服务器已经启动监听窗口中')
})
七,其他响应设置
-
res.redirect() 跳转响应
-
res.download() 下载响应
-
res.json() 响应
-
res.sendFile() 响应文件内容
八,中间件
真的不想写啊:
全局中间件
//导入express模块
const express = require('express')
// 创建应用对象
const app = new express();
const fs = require('fs')
function abc(req,res,next){
let {ip,path} = req;
console.log(ip,path);
res.writeHead(200,{'Content-Type':'text/html;charset=utf-8'});
fs.appendFileSync('./存储.txt',`${ip} ${path}\r\n`);
next();
}
app.use(abc)
app.get('/test1',(req,res)=>{
res.end('test1页面')
})
app.get('/test2',(req,res)=>{
res.end('test2页面')
})
app.all('*',(req,res)=>{
res.end('404')
})
app.listen(3000,()=>{
console.log('服务器已经启动监听窗口中')
})
路由中间件
顾名思义路由可以用,在路由定义的时候的形式参数的而第二个参数传入函数名字,就这样,真的不想写了
静态资源中间件
//导入express模块
const express = require('express')
// 创建应用对象
const app = new express();
app.use(express.static(__dirname + '/贪吃蛇小游戏'))
app.get('/',(req,res)=>{
res.end('HOME')
})
app.all('*',(req,res)=>{
res.end('404')
})
app.listen(3000,()=>{
console.log('服务器已经启动监听窗口中')
})
注意事项:
-
index.html文件为默认打开资源
-
如果静态资源于路由规则同时匹配,谁先匹配谁响应
-
路由响应动态资源,静态资源中间件响应静态资源
十,防盗链
//导入express模块
const express = require('express')
// 创建应用对象
const app = new express();
app.use((req, res, next) => {
const refer = req.get('referer')
if (refer) {
let url = new URL(refer);
let hostname = url.hostname;
if(hostname !== 'localhost'){
res.status(404).send(`<h1>找不见</h1>`)
}
}
next();
})
app.use(express.static('./test'))
app.listen(3000, () => {
console.log('服务器已经启动监听窗口中')
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h2>这是静态资源中间件</h2>
<img src="http://localhost:3000/img/练习.jpg" alt="">
</body>
</html>
十一,模块化路由
const express = require('express');
const router = new express.Router
router.get('/',(req,res)=>{
res.end('HOME1')
})
router.get('/home',(req,res)=>{
res.end('HOME2')
})
router.get('/admain',(req,res)=>{
res.end('HOME3')
})
router.get('/login',(req,res)=>{
res.end('HOME4')
})
router.all('*',(req,res)=>{
res.end('404')
})
module.exports = router;
//导入express模块
const express = require('express')
// 创建应用对象
const app = new express();
const homerouter = require('./homerouter')
app.use(homerouter);
app.listen(3000,()=>{
console.log('服务器已经启动监听窗口中')
})
十二,模板引擎
学了没坏处,但是现在不想学,前后端分离都用vue了,还直接上手吗?
十六,MYSQL
以编程写代码的形式操作数据库里的内容
要说数据库最重要的就是增删改查了
查询数据select 插入数据insert into 更新数据update 删除数据delete
sql语法:
where条件 and和or运算符 order by排序 count(*)函数
一,数据查询
一,查询
-- 通过*把user表中的数据全部查询
SELECT * FROM `user`
-- 查询表中的任意数据
SELECT `账号` FROM `user`
二,添加
-- 插入信息
INSERT INTO user(id,`姓名`,`账号`,`密码`) VALUES (4,'adasda',123456,123456)
-- 插入后需要重新查看
SELECT * FROM `user`
三,更新
-- UPDATE 表名称 SET 列名称 = 新值 WHERE 列名称 = 某值
UPDATE `user` SET `姓名` = '李四' WHERE id = 4
SELECT * FROM `user`
四,删除
-- 删除操作
DELETE FROM `user` WHERE id=4
-- SELECT * FROM `user`
二,where和or和and
where运算符
操作符 | 描述 |
---|---|
= | 等于 |
<> | 不等于 |
> | 大于 |
< | 小于 |
>= | 大于等于 |
<= | 小于等于 |
BETWEEN | 在某个范围内 |
LIKE | 搜索某种形式 |
sql版本呢较老的话不等于写成!=
and和or运算符
and相当于&&与
or相当于||或
三,操作mysql数据库
一,链接数据库
const mysql = require('mysql')
const db = mysql.createPool({
host:'127.0.0.1', //数据库ip地址
user:'root', //登录数据库账号
password:'123', //登录数据库密码
database:'mytest' //指定要操作那个数据库
})
db.query('select 1',(err,result) => {
if(err){
console.log('链接失败',err.message)
}else{
//注意执行的是select语句结果是数组
console.log('数据库连接成功')
}
})
二 ,操作数据库
标签:node,express,console,log,res,知识,学习,fs,const From: https://www.cnblogs.com/laonianrenws/p/17576041.html