1.模块化
NodeJS中每个.js文件都是一个独立的模块,给.js文件默认提供了一个名称为module的对象,用于指代当前文件,可以通过module导出当前模块中数据
NodeJS中当模块开始使用时,会出现另一个概念:包
默认情况下NodeJS中模块和包都是同一个概念
模块当成一个独立的js文件
包当成存放多个模块的文件夹
2.系统模块
NodeJS默认提供的系统模块,如fs文件系统、net网络模块、http网络处理模块等,在项目应用中不需要安装可以直接使用的模块
一个模块可以被引入多次,但是只会生效依次
第一次引入一个模块时,会将这个模块通过名称进行缓存
后面再次引入时根据名称进行判断是否已经引入
如果已经缓存了,说明已经引入了,直接从缓存提取
自定义模块与系统模块
默认情况下,应用中优先引入系统模块,然后引入加载自定义模块
引入的模块不带路径,默认引入系统模块/第三方模块
引入的模块带有相对路径,默认引入自定义模块
3.NodeJS常见模块
系统模块:path,处理文件路径的模块
const path = require('path')
//1.原始拼接路径
console.log(__dirname+'/index.htm')
console.log(__dirname.substring(0,__dirname.lastIndexOf('\\'))+'/index.html')
//2.path模块处理路径
console.log(path.join(__dirname,'index.html'))
console.log(path.join(__dirname,'..','index.html'))
系统模块:url,处理和网址相关的数据
const url = require('url')
let myPage = 'https://www.baidu.com:80/s?wd=sdas'
//1.原始方式,获取协议
console.log(myPage.substring(0,myPage.indexOf('//')+2))
console.log(myPage.substring(myPage.indexOf('//')+2,myPage.lastIndexOf(':')))
//2.使用系统模块url
let urlObj = url.parse(myPage)
console.log(urlObj.protocal)
console.log(urlObj.hostname)
console.log(urlObj.query)
console.log(urlObj.port)
//3.系统提供了一个默认类型URL,替代URL模块
let urlObj2 = new URL(myPage)
console.log(urlObj2)
系统模块:querystrng模块
专门用于处理网址中查询字符串(不完整的网址)
const qstring = require('querystring')
let myPage = 'wd=sdas&version=1.0'
//{wd:'sdass',version:'1.0'}
//1.原始语法
let ps = {}
let obj = params.spit('&').forEach(valur=>{
ps[value.split('=')[0]] = value.split('=')[1]
})
console.log(obj)
//2.使用模块实现
let obj2 = qstring.parse(myPage)
console.log(obj2['wd'])
//3.第三方模块实现
const qs = require('qs')
let obj3 = qs.parse(myPage)
console.log(obj3) // {wd:'sdass',version:'1.0'}
NodeJS内建模块:http模块
const http = require('http')
const server = http.createServer((req,res)=>{
res.writeHead(200,{"Content-type":"text/html;charset=utf-8"})
res.write('<h1>localhost:3000</h1>')
res.write('hello Nodejs')
res.end()
})
server.listen(3000,err=>{
console.log('服务器已经启动')
})
4.网络应用基础理论
1.服务端、客户端
软件根据使用方式、可以分为单机软件、网络软件
-单机软件:不需要联网直接使用的软件
-网络软件:需要联网才能操作的软件
网络软件,根据它安装、使用和更新方式的不同,区分为:
-B/S结构:Browser/Server结构
用户只需要安装一个浏览器,就可以使用软件的全部功能,包括基础、更新
用户不需要安装额外的软件、使用的软件也不需要用户主动更新
-C/S结构: Client/Server结构
用户需要下载一个软件安装包,安装到计算机中才能使用
如果软件出现了更新,需要重新下载新的安装包或者更新安装包才能让软件继续使用
网络软件中是数据共享问题:服务端、客户端
-服务端:工作在网络上的一个主机,提供数据服务的一端
-客户端:用户在网络上的一个主机,使用数据的一端
网络的分类-单机网络:一台电脑没有接入网络的情况下称为单机网络/单机
ip:127.0.0.1表示当前计算机,hostname:localhost表示当前计算机
-局域网络:局部区域的多台计算机组成的网络,一般IP地址192.168.xx或者10.10.xxx
-城域网络:一般以城市为单位划分的网络区域
-广域网络:全球www网络
网络ip地址
IP地址分为IPv4和IPv6地址,主要用于在网络中唯一标识一台计算机
IPv4地址,由4段二进制数据组成,转换成10进制:0-255
IPv6,由十六进制组成,主要原因IPv4地址已经慢慢不满足全球计算机数量的唯一标识
目前主流的IP地址还是IPv4主要分为5大类
A类,主要用于大型网络,1.x.x.x-127.x.x.x,10.x.x.x主要用于A类局域网,127.0.0.1当前主机
B类,主要用于中型网络,128.x.x.x-191.x.x.x
C类,主要用于小型网络,192.x.x.x-233.x.x.x,192.x.x.x主要用于c类局域网
D类,主要用于广播地址
E类,保留地址
2.网络协议和数据共享
网络:让所有的计算机都支持一些公共协议,在不同的场合中使用不同的协议
ISO:国际标准化组织
ECMA:欧洲计算机制造协会联盟
制定了网络通信协议,名称为开放互联模型(OSI/RM),规范并推广了常见的网络协议
关于OSI/RM模型:规范了多台计算机在网络中如何正确发送和接受是数据的规则
后端编程语言,支持的网络编程中,一般操作
-应用层协议,如FTP文件传输、SSH隧道协议、HTTP超文本传输协议…
-传输层协议,应用层协议的基础实现,主要有TCP端对端可靠协议、UDP广播协议
5.NodeJS WEB
1.第一个WEB应用
创建一个WEB应用,新建一个应用文件夹:demo03WEB/
执行命令、初始化Node应用
cd myweb
npm init
创建第一个应用模块 app.js
const http = require('http')
const server = http.createServer(function(req,res){
//req:用户的请求对象
//res:返回数据响应对象
res.writeHead(200,{"Content-type":"text/html;chartset=utf8"})
res.write('hello')
res.end
})
server.listen(3000,function(err){
console.log('服务器已在300端口启用')
})
2.问题处理
文件名错误
项目文件夹创建了自己的js文件,文件名称如node.js、http.js,导致项目出现意料之外的错误
解决方法:避免发现敏感的文件或者文件夹名称
拼写问题
开发过程中,部分单词拼写错误
解决方法:仔细排查,认真查看错误提示
项目启动报错
Error: listen EADDRINUSE: address already in use :::3000
错误:监听地址出现错误,地址对应的3000端口已经被占用
查询系统中占用端口的进行编号,打开命令行,执行命令查询哪个应用占用了该端口
netstat -ano | findstr 3000
打开任务管理器,启动PID选项
根据查询到的进行编码,结束对应的程序
重新启动项目,就不会再出现端口被占用的情况
3.路径判断
一个成熟的项目一般会包含很多的功能,并不是通过一个唯一的url地址进行访问,如可以通过/login访问登录页面、/index访问主页、/register访问注册页面
关于用户请求地址:url
完整地址:http://127.0.0.1:3000/index?name=“tom”
http://协议
127.0.0.1:ip地址
port:端口
/index:访问资源路径
?name=“tom”: 参数数据
如果要通过不同的URL地址路径,访问不同的功能,需要改变上述地址中的资源路径
资源路径是用户请求的一部分,可以获取并判断资源路径,操作吹请求对象
const http = require('http')
const path = require('path')
const server = http.createServer((req, res) => {
let pathname = req.url
res.writeHead(200, { 'Content-type': 'text/html;charset:utf-8' })
if (pathname.endsWith('favicon.ico')) {
res.write("")
} else if (pathname.endsWith('login')) {
res.write('<h2>会员登录页面</h2>')
} else if (pathname.endsWith('register')) {
res.write('<h2>会员注册页面</h2>')
} else if (pathname.endsWith('index')) {
res.write('<h2>系统首页</h2>')
} else {
res.write('页面找不到')
}
})
server.listen(3000, err => {
console.log('服务器已在3000端口启用');
})
4.访问网页
传统的项目中,用户发送与以恶搞URL地址,服务器会返回一个HTML网页个用户展示,NodeJS中则需要结合http和fs完成网页数据的返回
const http = require('http')
const path = require('path')
const fs = require('fs')
// 创建服务器
const server = http.createServer((req,res)=>{
// 接受用户请求
let pathname = req.url
// 设置请求头
res.writeHead(200,{'Content-type':'text/html;charset=utf-8'})
if(pathname.endsWith('favicon.ico')){
//过滤一个无效的路径
res.write('')
}else if(pathname.endsWith('index.html')) {
const content = fs.readFileSync(
path.join((__dirname,'html','index.html'),'utf-8')
)
res.write(content)
}else {
// 返回404错误
res.write('404 not fond')
}
})
server.listen(3000,err=>{
console.log('服务已在3000端口启动');
})
5.读取样式
一个完整的网页,不仅包含HTML文档,同时会包含样式文件、JS脚本文件,这些文件内容的数据较多,无法一个一个读取,需要通过一些共同的读取文件内容的代码进行封装,完成任意文件的读取
const http = require('http')
const path = require('path')
const url = require('url')
const fs = require('fs')
const server = http.createServer((req, res) => {
// 获取用户访问路径,转换成URL对象
let pathname = req.url
let urlOjb = url.parse(pathname)
pathname = urlOjb.pathname.substr(1) // html/index.html
// 读取文件
fs.readFile(path.join(__dirname, pathname), (err, data) => {
if (pathname.endsWith('.html')) {
res.writeHead(200, { 'Content-type': 'text/html;charset=utf-8' })
res.write(data)
res.end()
}else if(pathname.endsWith('.css')) {
res.writeHead(200,{"Content-type":'text/css'})
res.write(data)
res.end()
}else if(pathname.endsWith('.js')) {
res.writeHead(200.{'Content-type':'application/x-javascript'})
res.write(data)
res.end()
}
})
})
server.listen(3000,err=>{
console.log('服务器已在3000端口启用');
})
6.读取图片
需求:NodeJS开发的应用中,需要返回图片数据
const server = http.createServer((req, res) => {
let pathname = req.url
let urlObj = url.parse(pathname)
pathname = urlObj.pathname.substr(1)
if (pathname.endsWith('.webp')) {
res.writeHead(200, { 'Content-type': 'image/webp' })
const stream = fs.createReadStrenam(path.join(__dirname, pathname))
const resData = []
if (stream) {
stream.on('data', chunk => resData.push(chunk))
stream.on('end',()=>{
const finalData = Buffer.concat(resData)
res.end()
})
}else {
// 读取文件
fs.readFile(path.join(__dirname,pathname),(err,data)=>{
...
})
}
}
})
注:所有除案例之外的代码都未经调试,可能存在一些小问题,若需要可直接运行的代码,请查看对应案例
6.综合案例(使用express开发一个简单的用户登录过程)
移步(express实现简单用户登录过程)https://blog.csdn.net/weixin_44978043/article/details/120925620[]