NodeJs
NodeJs
EchoNode.
1.简介Node.js
不能单纯的使用js做后端开发 需要通过node.js
在使用js 做后端开发的时候需要借用Node.js
1.1 Node .js中包含的js运行环境
Node.js使一个基于chrome V8引擎的JavaScript
总结:浏览器是js的前端运行环境 Node.js 是js的后端的运行环境
Node.js包含了以下两个核心的内容
- cream V8的引擎
- Node.js的内置的API(API 是接口是通道 是用来负责一个软件和另外一个软件的沟通与交流的)
- Node.js中不能使用DOM和BOM操作的
1.2Node.js 作用
Node.js 是底层 基于Node.js的底层可以在此基础上做很多事情
1.3 Node.js 学习路线
- JavaScript 的基础语法
- Node.js内置API模块
- 第三方API模块 mysql 等
1.4 终端
终端是为程序员设计的人机交互的一种方式
- 终端的使用
打开终端, node 后面接 文件名 - 终端中的快捷键
上箭头 :定位到上一次执行的命令
Tap:自动补全
Esc:清空当前输入的命令
输入cls:清空终端的所用的命令
1.5 Buffer(缓冲器)
buffer 是一个和数组类似的
2.文件系统模块
fs 是Node.js 官方提供的 用来对文件进行读写
2.1 导入 fs
通过这行命令来导入fs模块
require 需求 需要做(某事)
1 | const fs=require('fs'); |
2.2 文件的读取与写入
fs.readFile() 读取文件内容
fs.readFile(path,[options],callback)
path 路径 options 选择 callback 回收
参数1:读取文件的路径
参数2:读取文件的时候采用的编码格式
参数3:回调函数function(err ,dataStr)err失败的信息 dataStr 成功的信息
1 | const fs=require('fs'); |
fs.writeFile(path ,要写入的内容,callback)
1 | const fs=require('fs'); |
调用fs模块来写入文件
1 | cosnt fs=require('fs'); |
flag 标记
r read :只读
w write :只写
a append :追加
如果要想文件的后面的内容可以追加 只需要将文件的flag设置为a
1 | const fs=require('fs'); |
2.3 异步写入文件
**同步就是等结果返回后再执行 **
异步就是不等返回结果就开始执行
判断是同步还是异步执行就在回调函数中和 外部输出 查看返回结果
fs.writeFileSync(‘路径’,’内容)
1 | fs.writeFileSync('./1,txt','ddddddd'); |
2.4路径动态拼接、
如果是以相对路径来看就很容易出现路径错误
解决方法:直接提供完整的文件提供路径来执行 同时在js中/表示的是转义的意思我们需要手动的去 加一个/ 来解决
1 | const fs=require('fs'); |
但是提供完整的存放路径可以解决路径拼接的问题 但是移植性很差
–dirname 表示当前文件所处的位置
–dirname
使用dirname 拼接当前文件的名称的方式就能解决 移植性差的问题
1
2
3
4
5
6
7
8
9
10const fs=require('fs');
console.log(__dirname);
fs.readFile(__dirname+'/1.txt','utf8',function(err,dataStr){
if(err){
return console.log('cw');
}else{
return console.log(dataStr);
}
} )
2.5 文件的写入场景
当我们需要持久化保存数据的时候我们就需要文件写入
- **文件的下载 **
- 文件的安装
- 日志 (聊天记录)
- 数据库
- 网盘
2.6 文件写入流
引入fs模块 创建写入流对象
1 | const fs=require('fs'); |
对于简单的写入较少的情况想使用writeFile
对于多次 写入较多文件的情况下使用CreteWriteStream
2.7 文件的读取
fs.readFile(‘path’,回调函数(err(错误对象),data(读取成功后的文件内容)))
//同步读取
fs.readFileSync(‘文件路径’);
1 | const fs=require('fs'); |
2.8 读取文件流
1 | const fs=require('fs'); |
2.9 文件的复制
1 | const fs=require('fs'); |
通过node.js 自带的copy方法也能实现文件的复制
1 | const fs=require('fs'); |
2.10 文件的重命名
- 引入fs模块
- 调用rename()方法
raname(‘目标文件’,‘新的文件’,回调函数)。
1 | const fs=require('fs'); |
2.11 删除文件
1 | fs.unlink('路径',回调(err){ |
2.12 文件夹操作
- 创建 文件夹
- 删除文件夹
- 读取文件夹
1 | const fs=require('fs'); |
2.13 获取文件的状态
不能通过文件的名称来判断文件的类型
**stats 接收的回调是一个对象 **
1 | const fs=require('fs'); |
文件创建练习
像这种 异步的任务下面有回调函数 然后还有 回调 就称为回调地狱
1 | const fs=require('fs'); |
3.path 路径模块
path 是Node.js官方用来处理路径的模块 满足用户对路径处理的需求
3.1 path 导入
1 | const path=require('path'); |
3.2 路径拼接 join
join 方法可以把多个路径片段拼接成一个完整的路径片段
注意:../ 这个会抵消掉前面的一层路径
1 | const path=require('path'); |
上面代码输出为:\a\b\d
在后面如果要使用路径拼接的时候就只用path方法
1 | const path=require('path'); |
3.3 获取路径的最后部分 basename
使用path.basename()方法可以获取路径中的最后一部分 通常用啦获取文件中的文件名
**path.basename(文件路径path,文件的后缀名) **
**第二个 参数是是否去掉文件的后缀名 **
const path=require('path');
const fpath='a/b/b/index.html';
//获取完整的文件名 包括后缀
let fname=path.basename(fpath);
console.log(fname);
//返回值 index.html
//清楚掉后缀
let fname2=path.basename(fpath,'.html');
console.log(fname2);
//返回值 index
3,4 获取文件的扩展名 extname()
path.extname( 文件路径 )
返回值是文件的后缀名
1 | let fname3=path.extname(fpath); |
4.缓冲器
buffer 是一个和数组类似的对象 但是是专门用来保存二进制的
- buffer 的初始化
1
2
3const buf1=Buffer.alloc(10);创建一个10字节的buffer
const buf2=Buffer.clocUnsafe(10);
const bur3=Buffer.from('字符串'); 返回的是与字符对应的ascll - Buffer 数据的读取
1
2const buf3=buffer.from('ddd');
console.log(buf3[0]); - 设置
1
buf[1]=00;//直接修改
- buffer 溢出
**8 个2进制位能保存的最大的是255 如果这个数字超过255的话 **
高于8位的二进制位就会被舍弃
1 | #### 介绍 |
5.http协议
**超文本传输协议 都遵守这种约定来进行数据的传输 **
5.1 网页的加载过程
四次 浏览器向服务器发送请求 服务器向浏览器返回响应
5.2 请求报文
请求报文由四个部分组成
请求行
三段内容组成:
- 请求方式 :常见的就是get 个psot 其他的用的相对较少
- **URL: **
** 组成:**
协议 :****https 、 http mongodb ftp ssh 协议
**域名 : **www.badu.com 域名IP地址
路径 : /s
查询字符串:rsv_spt=1 & rsv_iqid=0xd1044 表示的是映射的关系 参数
- HTTP/1.1 HTTP协议的版本 这个一般是固定的
请求头 格式:请求头的名字:请求头的值
1
2
3
4
5
6
7
8
9
10请求行 GET https://www.baidu.com /?tn=80035161_1_dg HTTP/1.1
请求头 Accept: text/html, application/xhtml+xml, image/jxr, */* 表明客户端所能接受的数据的类型
Accept-Language: zh-Hans-CN,zh-Hans;q=0.5 表明客户端支持的语言类型
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; Touch; rv:11.0) like Gecko 客户端的字符串标志
Accept-Encoding: gzip, deflate 表明客户端支持的压缩方式
Host: www.baidu.com 服务端的主机名
Connection: Keep-Alive 连接配置 Keep-Alive 保持连接 close 断开
Cookie: BD_UPN=1126314751; BD_HOME=1; Cookie 小甜饼
Cache-Control: max-age=120 缓存控制
Upgrade-Insecure-Requests: 1 强制浏览器发送请求时使用 https请求空行 在格式上做一些分割
请求体
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16请求体
POST https://processon.com/login HTTP/1.1
Accept: text/html, application/xhtml+xml, image/jxr, */*
Referer: https://processon.com/login?f=index
Accept-Language: zh-Hans-CN,zh-Hans;q=0.5
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; Touch; rv:11.0) like Gecko
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
Host: processon.com
Content-Length: 61
Connection: Keep-Alive
Cache-Control: no-cache
login_email=779498590@qq.com&login_password=GREM9pus.fek-soos请求体内容
1
login_email=779498590@qq.com&login_password=GREM9pus.fek-soos
form 表单
1
2
3
4
5<form method="post">
<input name="login_email">
<input name="login_password">
<input type="submit" value="登录"/>
</form>请求体的格式是非常灵活的, 不
1
5.3 响应报文
- 组成部分
响应行
协议的版本 HTTP/1.1
响应的状态码
- 200 成功
- 302 跳转
- 404 找不到资源
- 403 禁止的
- 500 服务器内部错误
1
2
3
4
5信息响应(100–199),
成功响应(200–299),
重定向(300–399),
客户端错误(400–499)
服务器错误 (500–599)响应的状态字符串
**响应的状态字符串 **
响应头
响应头格式与请求头格式一致 『名字: 值』
1
2
3
4
5
6
7
8
9
10
11
12
13Bdpagetype: 1
Bdqid: 0xf4330ae2000009bd
Cache-Control: private
Connection: keep-alive
Content-Type: text/html;charset=utf-8
Date: Sat, 07 Nov 2020 03:08:03 GMT
Expires: Sat, 07 Nov 2020 03:08:03 GMT
Server: BWS/1.1
Set-Cookie: BDSVRTM=12; path=/
Strict-Transport-Security: max-age=172800
Traceid: 1604718483242292455417596420134845548989
X-Ua-Compatible: IE=Edge,chrome=1
Content-Length: 289603Bdpagetype 和 Bdqid 为百度自定义的响应头
- Cache-Control 缓存控制 private 只允许客户端缓存数据 public
- Connection 连接设置
- Content-Type 『响应体』内容的类型
- https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Basics_of_HTTP/MIME_types
- text/html 表明响应体为 HTML 内容
- text/css 表明响应体为 CSS 内容
- application/javascript 表明响应体为 JavaScript
- image/png 表明响应体为 png 的图片
- Date 响应时间
- Expires 过期时间
- Server 服务器信息
- Set-Cookie 设置 cookie
- Strict-Transport-Security 响应头与Upgrade-Insecure-Requests结合使用
- Traceid 跟踪 id
- X-Ua-Compatible IE=Edge,chrome=1 强制IE浏览器使用最新的解析器解析网页, 使用 chrome 的内核解析网页
- Content-Length 响应体的长度
响应空行
响应体
响应体格式比较灵活, 场景的格式有
- HTML
- JavaScript
- CSS
- JSON
- **图片 **
5.4Cream 查看请求报文与响应报文( 重要 )
5.5 创建HTTP服务
- 引入模块
- 调用方法 创建服务对象
- 监听端口 启动服务
1 | //1. 引入 http 模块 |
5.6 请求报文的请求方式
1 | //1. 引入 http 模块 |
5.7响应报文的一些api
1 | const http=require('http'); |
5.8 Http 练习(多个)
背景变色
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30const http = require('http');
const url = require("url");
const server = http.createServer((request, response) => {
//设置响应头
// response.setHeader('Content-Type','text/html;charset=utf-8');
// 获取请求 url 中的 『bg』参数
let bg = url.parse(request.url, true).query.bg ? url.parse(request.url, true).query.bg : '#edf'
//设置响应体
response.end(`
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<style>
body{
background: ${bg};
}
</style>
</head>
<body>
<h1>
身是菩提树,心如明镜台,时时勤拂拭,勿使惹尘埃。
</h1>
</body>
</html>
`);
});
server.listen(80);数据表格加载、
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42const data=[
{id:1,
name:'hahah',
song:'dfjasdf'},
{
id:2,
name:'dfsadsf',
song:'dadfewfghh'
}
];
const http=require('http');
const fs=require('fs');
const server=http.createServer(function(request, response){
let str='';
for(let i=0;i<data.length;i++){
str+=`<tr><td>${data[i].id}</td><td>${data[i].name}</td><td>${data[i].song}</td></tr>`;
}
response.end(`
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<table>
<tr><td>id</td><td>name</td><td>song</td></tr>
${str}
</table>
<script src='127.0.0.1/'></script>
</body>
</html>
`);
} );
server.listen(80,function(){
console.log('80 ');
} )不同请求返回不同结果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29//根据不同的路径来返回不同的结果
const http=require('http');
const url=require('url');
const server=http.createServer(function(reqeust,respons){
//获取请求类型 gat
let method=request.method;
//获取路径
let pathname=url.parse(reqeust.url,true).pathname;
//判断 看是什么请求
if(mathod.toUpperCase()==='GET'&&pathname==='/login'){
respons.write('登录');
}
if(mathod.toUpperCase()==='GET'&&pathname==='/register'){
respons.write('注册');
}else{
respons.end('<h1>404 not found<h1>');
}
} );
server.listen(80,function(){
console.log('cg');
} )响应js代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58const data=[
{id:1,
name:'hahah',
song:'dfjasdf'},
{
id:2,
name:'dfsadsf',
song:'dadfewfghh'
}
];
const http=require('http');
const fs=require('fs');
const url=require('url');
const server=http.createServer(function(request, response){
//---------存在中文解码错误的问题 所以需要我们调用一个一个函数来对中文路径来进行解码
//decodeURL 能对中文路径进行解码
let pathname=decodeURI(url.parse(request.url,true).pathname);
//如果请求为路径为 变色.js的话就返回解析后的js
if(pathname==='/dome'){
let str='';
for(let i=0;i<data.length;i++){
str+=`<tr><td>${data[i].id}</td><td>${data[i].name}</td><td>${data[i].song}</td></tr>`;
}
response.end(`
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<table>
<tr><td>id</td><td>name</td><td>song</td></tr>
${str}
</table>
<script src='127.0.0.1/变色.js'></script>
</body>
</html>
`);
}else if(pathname==='/变色.js'){
let js=fs/readFileSyns('./变色.js');
response.end(js);
console.log('cssdfsafasdfsa');
}else{
response.end('404');
}
} );
server.listen(80,function(){
console.log('80 ');
} )根据路径响应文件内容
使用 url.parse()方法将路径解析为一个方便操作的对象。
第二个参数为 true 表示直接将查询字符串转为一个对象(通过query属性来访问)发get请求 如果是/index .html 就返回 public/index.html 的内容返回
如果是其他的就返回其他的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21const http=require('http');
const fs=require('fs');
const url=require('url');
const server=http.createServer(function(request,response){
const pathname=(url.parse(request.url,true)).pathname;
if(pathname==='/index.html'){
let html=fs.readFileSync('./index.html');
response.end(html);
}else if(pathname==='/css'){
let css=fs.readFileSync(__dirname+'/css/app.css')
response.end(css);
}else{
response.end('ddddddddd');
}
} )
server.listen(80,function(){
console.log('服务已经启动 80端口监听中');
} )**路径响应 **
fs.readFile(filePath,function(err,data){
if(err){ 404}
else{ data}
})