Part1:
1.url模块
浏览器是一个非常神奇的东西, 当我们在浏览器的地址栏里输入一段地址的时候,他就会帮我们给服务器发送一个请求,这个请求会被服务器解析成稀奇古怪的模样,从而浏览器发生页面跳转,数据变更等等一系列神奇的事情。
比如,当我们在百度上搜索一个hello的时候注意观察,百度地址栏里发生了啥
后面跟上了一串代码, 通过前面的学习我们知道这是浏览器在以
GET的方式对服务器进行数据的传递。前端在做什么我们知道,那么后端在做些啥那?
URL解析:
文档请参照
nodejs url文档
这是干啥的 : 进行地址栏操作的模块。
url.parse(urlString) //字符串类型解析成对象
url.format(urlObject) //对象类型转字符串
url.resolve(from,to) //路径拼接
小技巧:
先看下 一个关系图:
URLSearchParams和URL方法:
URL是创建url对象用的东西, RULSearchParams 这玩意是专门用来查询url之中传递的数据的。但是他们之间的关系有那么一些小复杂
const
{
URL
,
URLSearchParams
}
=
require
(
"
url
”);
来个脑筋急转弯:
let
urlSearchParams
=
new
URLSearchParams
(
myUrl
.
search
);//错误,只能urlSearchParams=myUrl.searchParams;这样才能改变myurl的参数
urlSearchParams
.
set
(
"
abb
"
,
"
456
"
);
console
.
log
(
urlSearchParams
);
console
.
log
(
myUrl
.
href
);
//这里的结果是啥? 我们对urlSearchParams的操作是否会影响到 myUrl那?
parse:
某些特殊地址:
比如图片,cdn加速的东西啥的,都喜欢用这样的方式来进行地址的传递:
这类地址有一个非常形象的名字叫做:
免协议地址 。
那么我们在解析免协议地址的时候:
会被解析成这个熊样 :
Url {
protocol: 'https:',
slashes: true,
auth: null,
port: null,
hash: null,
search: '?abc=123',
query: 'abc=123',
pathname: '/',
path: '/?abc=123',
这真的是木有协议了! 你可以直接粘贴这段代码到浏览器上, 浏览器会返回给你一个file://的协议,变成本地磁盘找寻。
Url {
protocol: null,//协议,如http
slashes: null,
auth: null,
host: null,
port: null,
hostname: null,
hash: null,
search: null,
query: null,
遇到这样的地址真的没法解析了么?
当然不是,看下
文档 ,注意文档的第三个参数。
所以只要将:url.parse() 第三个参数改成true,就万事大吉了。
format
逆运算,obj => string。
resolve
域名和路径的集合:
查看这个结果看功能:
Url.resolve(“http://www.baidu.com”,”/b”)
查看这个结果看真实作用:
2.queryString 模块
文档请参照
nodeJS queryString文档
queryString.parse(str,[,sep[,eq[,options]]])
Tip:所有可选参数都是用来对str 进行分割处理的。
例如 :
console
.
log
(
qs
.
parse
(
'
name:zhangsan,age:20
'
,
'
,
'
,
'
:
’))
第二个参数
,
其含义为以
,
为分割依据,将该字符串以
,
为间隔进行划分,结果是分成两组数据;(该参数默认为 & )
console
.
log
(
qs
.
parse
(
'
name:zhangsan,age:20
'
,
'
,
'
,
'
:
’)) => 据此逗号将字符串分割成 { name:”zhangsan” , age:”20” }
第三个参数 : 其含义为分割每组数据中的字段名和字段值, 以 name:zhangsan为例 , 字段名为name , 字段值为 zhangsan;
queryString.stringify用法与其正好相反,即逆运算
3.http模块
创建一个web服务器
获得接口数据(http.get)
小爬虫(http.request的get)
模拟表单提交(http.request 的 post);
开启一个服务器 (
createServer
方法) :
const
http
=
require
(
"
http
"
);
var
server
=
http
.
createServer
((
request
,
response
)
=>
{
response
.
writeHead
(
200
,{
"
Content-Type
"
:
"
text/html
"
});
response
.
write
(
"
hello world
"
);
response
.
end
();
})
server
.
listen
(
8080
,
"
localhost
"
,
()
=>
{
})
获取接口数据:(http.get)
查看文档
它,你是否还记得。 $.ajax 系列方法你是否还记得, 如果记得那就好办了, 这玩意和他一样的。
$.get() === http.get()
文档案例;
改造案例 ,请求
https://api.douban.com/v2/movie/top250 接口获取数据;
Content-type是啥意思。
以下来自于文档中的代码主要负责查看文档数据类型,是否为json类型。
/*——start
const
contentType
=
res
.
headers
[
'content-type'
];
let error
;
if
(
statusCode
!==
200
)
{
error
=
new
Error
(
'请求失败。
\n
'
+
`状态码
:
$
{
statusCode
}
`
);
}
else
if
(!
/^application\/json/
.
test
(
contentType
))
{
error
=
new
Error
(
'无效的 content-type.
\n
'
+
`期望
application
/
json 但获取的是 $
{
contentType
}
`
);
}
if
(
error
)
{
console
.
error
(
error
.
message
);
// 消耗响应数据以释放内存
res
.
resume
();
return
;
}
End --*/
事件 data , end
在get中 绑定事件:
res
.
setEncoding
(
'
utf8
'
);
res
.
on
(
"
data
"
,(
chunk
)
=>
{
console
.
log
(
chunk
);
});
res
.
on
(
"
end
"
,()
=>
{
console
.
log
(
"
数据加载结束
"
)
});
每次触发都会有一个buffer传过来一个二进制对象,但是你要知道我们需要的是utf8编码的数据,所以会设置setEncoding。
爬虫 http.request()
查看文档
SEO优化是个啥?
cheerio 为爬虫而生的一个 jQuery核心模块。
这货提供了jQuery的选择器,还有jQueryDOM操作的方法,让你可以方便的捕获页面中的内容。
现在回顾一下jQuery的DOM操作有些啥?
爬虫程序:
Tip:请及时关闭爬虫,要不然你的电脑会遭殃的.....
4.fs模块 (filesystem)
NodeJS内置了一个fs模块,可以读取和写入文件,这是和前端最大的区别。详细内容请参照
NodeJS fs模块文档。
fs模块的特性是其提供了同步和异步两种方式对文件进行读写。 回顾JavaScript的异步程序可知, JavaScript是一个单线程的语言, 这个单线程语言,存在一个特殊队列这个队列叫做异步队列。
异步:
文件 I / O: 就是对 POSIX 函数的封装, 什么是POSIX 那,这货是一个操作系统为应用程序提供的通用接口标准, 说白了,就是有了它你就可以用你的代码对计算机上的文件进行操作了。
同步I O / 异步I O:
主要方法:
异步类方法:
文件信息:
stat()
创建文件夹:
mkdir()
读取信息:
readFile()
写入信息:
writeFile() //dom = text;
AppendFile() //dom += text;
列出目录内容:
readdir()
重命名目录
rename()
删除目录与文件:
rmdir , unlink
同步类方法:
异步文件 I / O :
使用:readFile方法,点击
查看文档。
/内置模块的使用需要我们在使用的时候优先去加载一下这个模块。
var
fs
=
require
(
"
fs
"
);
//readFile 方法是 fs 的异步文件IO操作方法,在该方法执行的时候,后续代码依旧可以执行;
fs
.
readFile
(
'
test.txt
'
,
'
utf-8
'
,
function
(
err
,
data
)
{
if
(
err
)
{
console
.
log
(
err
);
}
else
{
console
.
log
(
data
);
}
});
console
.
log
(
1
);
非常简单的调用,让nodejs得到了对应的文件,但是请不要忽略,在文件下方的 console.log(1); 这个玩意非常关键。
目录结构为:
fs/
fs.js
text.txt // 任意内容,但是编码必须是 utf-8,因为在上文方法中有限制。
当我们在执行 : node fs
得到的结果是:
1
…/文档内容
结合上面的内容想一下,为啥优先执行的是 1 那 ?
读取图片:
同步文件 I / 0 :
+ Sync
Strem 模块
这个模块更像是一个概念, 在http模块中中get方法中的 request 就是加载之后的返回值,这货就是一个流,这个流是啥东西那?就是一个可被处理的数据, 既然叫做流,肯定会动么, 所以这货也有很多的事件。流那总共分成四个类型, 共有四个常用事件。
流的分类-四种:
Readable - 可读操作。
Writable - 可写操作。
Duplex - 可读可写操作.
Transform - 操作被写入数据,然后读出结果。
复制文件:
let read = fs.createReadStream();
Let write = fs.createWriteStream();
read.pipe(write);
流的特性:
Const zlib = requier(“zlib”);
let read = fs.createReadStream();
Let write = fs.createWriteStream();
read.pipe(zlib.createGzip()).pipe();
事件:文档
data - 当有数据可读时触发。
end - 没有更多的数据可读时触发。
error - 在接收和写入过程中发生错误时触发。
finish - 所有数据已被写入到底层系统时触发。
事件 Event模块
事件定义:
on()
once()
事件触发:
emit()
事件删除:
removeAllListener()
事件增加:
perpendListener()
事件属性:
绑定最大数量:默认为10 getMaxListener();
设置最大数量:setMaxListener();
事件的原理是观察者模式。
const
EventEmitter
=
require
(
"
events
"
);
class
myEvent
extends
EventEmitter
{
}
var
me
=
new
myEvent
();
me
.
on
(
"
event
"
,()
=>
{
console
.
log
(
"
事件触发
"
)
})
me
.
emit
(
"
event
”);
Part2:
路由:
根据请求参数不同,返回的内容不同。
var
http
=
require
(
"
http
"
);
var
url
=
require
(
"
url
"
);
var
fs
=
require
(
"
fs
"
);
var
server
=
http
.
createServer
((
req
,
res
)=>
{
// console.log(req.url);
if
(
req
.
url
!==
"
/favicon.ico
"
){
const
{
pathname
,
query
}
=
url
.
parse
(
req
.
url
);
if
(
pathname
===
"
/
"
){
let
content
=
fs
.
readFileSync
(
"
index.html
"
,
"
utf8
"
);
res
.
end
(
content
)
}else if
(
pathname
===
"
/list
"
){
let
content
=
fs
.
readFileSync
(
"
index.html
"
,
"
utf8
"
);
res
.
end
(
"
list
"
);
}else
{
res
.
end
(
"
404
"
);
}
}
res
.
end
(
"
hello world
"
);
})
server
.
listen
(
"
8000
"
);
req.url 代表的是访问的路径, 那么所谓路由就是根据访问路径的不同返回不同的内容。
路由的参数接受 :
你以为加载一张图片很简单?
<
img
src
=
"
/pic.png
"
alt
=
""
>
//读取二进制图片数据;
const
pic
=
fs
.
readFileSync
(
"
pic.png
"
,
"
binary
"
);
//设置请求头 返回二进制图片数据;
res
.
writeHead
(
"
200
"
,{
"
Content-type
"
:
"
image/png
"
});
res
.
write
(
pic
,
"
binary
"
);
res
.
end
();
npm script
在package.json中
这个属性可以进行长命令的缩减,进行指令的快速执行。
"
scripts":{
"
run":"
nodemon server.js"
}
其实不仅如此,你甚至可以设置非常多的linux指令,在命令行里进行操作
比如 ls mkdir echo