Node Web应用开发

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[]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值