Node.js入门html,css,js 30年了nodejs环境 09年出现 15
Node.js入门
html,css,js 30年了
nodejs环境 09年出现 15年
nodejs为我们解决了2个方面的问题:
- 【锦上添花】让我们前端工程师拥有了后端开发能力(开接口,访问数据库) - 大公司BFF(50+)
- 【✔️】前端工程化(Webpack,vit)
Node.js基本概念
Node.js中文官网
什么是Node.js
作用:
使用 Node.js 编写后端程序 / 支持前端工程化
- 后端程序:提供接口和数据,网页资源等
- 前端工程化:对代码压缩,转译,整合(使用各种工具,提升效率)
Node.js 为何能执行 JS?
首先:浏览器能执行 JS 代码,依靠的是内核中的 V8 引擎(C++ 程序)
其次:Node.js 是基于 Chrome V8 引擎进行封装(运行环境)
区别:都支持 ECMAScript 标准语法,Node.js 有独立的 API
注意:Node.js 环境没有 DOM 和 BOM 等
Node.js 安装
nvm
nvm是一个nodejs版本管理工具,它可以在我们电脑中安装多个node版本,并且可以随意切换版本
nvm官网:nvm文档手册 - nvm是一个nodejs版本管理工具 - nvm中文网
要求:使用nvm安装node 16.19.0(指定版本:为了兼容后期学习的项目)
# ✨安装node 16.19.0版本
nvm install 16.19.0# ✨查看node版本列表(带*号的表示当前使用的版本)
nvm ls# ✨切换node版本
nvm use 16.19.0
成功验证:打开 cmd 终端,输入 node -v 命令查看版本号如果有显示,则代表安装成功
使用 Node.js
修改终端默认执行程序
为了防止某些电脑默认使用的是PowerShell执行js报错,我们需要调整一下如下设置为`Command Prompt`
需求:使用nodejs执行一个js文件,使用console.log()打印三个五角星
步骤:
- 新建 index.js 文件,编写打印代码和 for 循环打印 3 个 五角星
- 命令:在 VSCode 集成终端中(ctrl+shift+` 打开),输入 node index.js,回车即可执行,并查看结果
注意:node 文件路径
console.log('Hello, World')
for (let i = 0; i < 3; i++) {console.log('☆')
}
Node.js 执行目标 JS 文件,需要使用 node index.js 命令来执行(我们可以借助 VSCode 集成终端使用,好处:可以快速切换到目标 JS 文件所在终端目录,利用相对路径找到要执行的目标 JS 文件
准备node项目
在vs code中编写node代码,默认是没有提示的,通过如下步骤创建一个可以有语法提示的node项目,方便接下来的学习。减轻学习负担
- 创建一个空白文件夹 ,例如:mynode
- 使用vs code打开 mynode文件夹
- 按ctrl + shift + `打开终端
- 在终端中输入:
npm install @types/node
后在此项目中编写nodejs代码就有提示了
注意:由于npm的镜像源在国外,需要切到国内才速度快
切换命令:npm set registry=https://repo.huaweicloud.com/repository/npm/
fs模块-读写文件
- 模块:类似插件,封装了方法和属性供我们使用
- fs 模块:是Node.js的内置模块,封装了与本机文件系统进行交互的,方法和属性
- fs 模块使用语法如下:
加载 fs 模块,得到 fs 对象
const fs = require('fs')
写入文件内容语法:
fs.writeFile('文件路径', '写入内容', err => {// 写入后的回调函数
})
读取文件内容的语法:
fs.readFile('文件路径', (err, data) => {// 读取后的回调函数// data 是文件内容的 Buffer 数据流
})
- 需求:向 test.txt 文件写入内容并读取打印
/*** 目标:使用 fs 模块,读写文件内容* 语法:* 1. 引入 fs 模块* 2. 调用 writeFile 写入内容* 3. 调用 readFile 读取内容*/
// 1. 引入 fs 模块
const fs = require('fs')
// 2. 调用 writeFile 写入内容
// 注意:建议写入字符串内容,会覆盖目标文件所有内容
fs.writeFile('./text.txt', '欢迎使用 fs 模块读写文件内容', err => {if (err) console.log(err)else console.log('写入成功')
})
// 3. 调用 readFile 读取内容
fs.readFile('./text.txt', (err, data) => {if (err) console.log(err)else console.log(data.toString()) // 把 Buffer 数据流转成字符串类型
})
path模块-路径处理
- 为什么在 Node.js 待执行的 JS 代码中要用绝对路径:
Node.js 执行 JS 代码时,代码中的路径都是以终端所在文件夹出发查找相对路径,而不是以我们认为的从代码本身出发,会遇到问题,所以在 Node.js 要执行的代码中,访问其他文件,建议使用绝对路径
- 新建 03 文件夹编写待执行的 JS 代码,访问外层相对路径下的文件,然后在最外层终端路径来执行目标文件,造成问题
- 问题原因:就是从代码文件夹出发,使用
../text.txt
解析路径,找不到目标文件,报错了!
- 解决方案:使用模块内置变量
__dirname
配合 path.join() 来得到绝对路径使用
const fs = require('fs')
console.log(__dirname) // D:\备课代码\2_node_3天\Node_代码\Day01_Node.js入门\代码\03// 1. 加载 path 模块
const path = require('path')
// 2. 使用 path.join() 来拼接路径
const pathStr = path.join(__dirname, '..', 'text.txt')
console.log(pathStr)fs.readFile(pathStr, (err, data) => {if (err) console.log(err)else console.log(data.toString())
})
- 再次执行查看问题就被修复了!以后在 Node.js 要执行的 JS 代码中访问其他文件的路径,都建议使用绝度路径
案例-压缩前端html
目标:压缩前端代码,让浏览器加载网页更快(体验前端工程化)
前端工程化:对代码压缩,转译,整合,测试,自动部署等等
需求:把public\index.html中 回车符(\r)和换行符(\n)去掉,写入到新 dist\index.html 中
步骤:
- 使用fs.readFile读取public\index.html中的内容
- 正则替换index.html中字符串 /[\r\n]/g
- 将替换后的新内容写入到新dist\index.html中 完成代码压缩
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>时钟案例</title><style>html,body {margin: 0;padding: 0;height: 100%;background-image: linear-gradient(to bottom right, red, gold);}.box {width: 400px;height: 250px;background-color: rgba(255, 255, 255, 0.6);border-radius: 6px;position: absolute;left: 50%;top: 40%;transform: translate(-50%, -50%);box-shadow: 1px 1px 10px #fff;text-shadow: 0px 1px 30px white;display: flex;justify-content: space-around;align-items: center;font-size: 70px;user-select: none;padding: 0 20px;-webkit-box-reflect: below 0px -webkit-gradient(linear, left top, left bottom, from(transparent), color-stop(0%, transparent), to(rgba(250, 250, 250, .2)));}</style>
</head>
<body><div class="box"><div id="HH">00</div><div>:</div><div id="mm">00</div><div>:</div><div id="ss">00</div></div>
</body>
</html>
/* 职责:将 public/index.html压缩代码:
1.使用fs.readFile读取public\index.html中的内容
2.正则替换index.html中字符串/rn]/g
3.将替换后的新内容写入到新dist\index.html中完成代码压缩
*/const { readFile,writeFile } = require("fs");
const path = require("path");// 1. 读取未压缩的index.html内容
let indexPath = path.join(__dirname, 'public/index.html')readFile(indexPath, (err, data) => {if (err) {console.log(err);} else {// console.log(data.toString())let unzipHtml = data.toString()// 2.正则替换index.html中字符串/rn]/gconst reg = /[\r\n]/gconst zipHtml = unzipHtml.replace(reg, '')// console.log(zipHtml)// 3.将替换后的新内容写入到新dist\index.html中完成代码压缩let targetPath = path.join(__dirname, 'dist/index.html')writeFile(targetPath,zipHtml,(err)=>{if(err){console.log(err); }else{console.log('写入成功');}})}
})
案例-压缩前端JS
需求:把准备好的 JS 文件代码的回车符,换行符,打印语句去掉,并插入到之前 html 内容之后
步骤:
- 读取 public/index.js 内容
- 使用正则替换内容字符串里的\r \n 和console.log('xxx')
-
- /[\r\n]/g
- /console.log\('.+?'\);/g
- 拼接 html 内容写入到 dist/index.html 内
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>时钟案例</title><style>html,body {margin: 0;padding: 0;height: 100%;background-image: linear-gradient(to bottom right, red, gold);}.box {width: 400px;height: 250px;background-color: rgba(255, 255, 255, 0.6);border-radius: 6px;position: absolute;left: 50%;top: 40%;transform: translate(-50%, -50%);box-shadow: 1px 1px 10px #fff;text-shadow: 0px 1px 30px white;display: flex;justify-content: space-around;align-items: center;font-size: 70px;user-select: none;padding: 0 20px;-webkit-box-reflect: below 0px -webkit-gradient(linear, left top, left bottom, from(transparent), color-stop(0%, transparent), to(rgba(250, 250, 250, .2)));}</style>
</head>
<body><div class="box"><div id="HH">00</div><div>:</div><div id="mm">00</div><div>:</div><div id="ss">00</div></div>
</body>
</html>
window.addEventListener('load', function () {console.log('测试-网页加载完成了');clock();setInterval(clock, 1000);
});
function clock() {console.log('测试-时钟函数调用了');let dt = new Date();let HH = dt.getHours();let mm = dt.getMinutes();let ss = dt.getSeconds();console.log(dt, HH, mm, ss);document.querySelector('#HH').innerHTML = padZero(HH);document.querySelector('#mm').innerHTML = padZero(mm);document.querySelector('#ss').innerHTML = padZero(ss);
};
function padZero(n) {console.log('时间测试');return n > 9 ? n : '0' + n;
}
/*** 目标二:压缩 js 里代码,并整合到 html 中一起运行* 2.1 读取 public/index.js 内容* 2.2 使用正则替换内容字符串里的,回车符\r 换行符\n 打印语句console.log('xxx');* 2.3 确认后,拼接 html 内容写入到 dist/index.html 内*/
const fs = require('fs')
const path = require('path')
fs.readFile(path.join(__dirname, 'public', 'index.html'), (err, data) => {const htmlStr = data.toString()const resultStr = htmlStr.replace(/[\r\n]/g, '')// 2.1 读取 public/index.js 内容fs.readFile(path.join(__dirname, 'public', 'index.js'), (err, data) => {const jsStr = data.toString()// 2.2 使用正则替换内容字符串里的,回车符\r 换行符\n 打印语句console.log('xxx');const jsResultStr = jsStr.replace(/[\r\n]/g, '').replace(/console.log\('.+?'\);/g, '')const result = `<script>${jsResultStr}</script>`console.log(result)// 2.3 确认后,拼接 html 内容写入到 dist/index.html 内fs.writeFile(path.join(__dirname, 'dist', 'index.html'), resultStr + result, err => {if (err) console.log(err)else console.log('压缩成功')})})})
http模块-创建Web服务
什么是Web服务?
Web 服务:是一种通过网络进行通信和交换数据的技术
- 大白话:一个程序,用来提供网上信息浏览功能
我们前端可以使用 Node.js来构建一个 Web 服务来与客户端进行数据交换
【前置知识】端口号
vision
http://8.138.119.204:80
创建3000端口的Web服务
基于 Node.js 环境,使用内置 http 模块,创建 Web 服务程序
需求:引入 http 模块,使用相关语法,创建 Web 服务程序,响应返回给请求方一句提示 ‘hello,world’
步骤:
- 引入 http 模块,创建 Web 服务对象
- 监听 request 请求事件,对本次请求,做一些响应处理
- 启动 Web 服务监听对应端口号
- 运行本服务在终端进程中,用浏览器发起请求 http://localhost:3000/
注意:
- 本机的域名叫做 localhost 或者 127.0.0.1
- 一个端口只能有一个服务监听,如果前一个服务器未关闭,则第二次启动会报错
/*** 目标:使用 http 模块,创建 Web 服务* Web服务:一个程序,用于提供网上信息浏览服务* 步骤:* 1. 引入 http 模块,创建 Web 服务对象* 2. 监听 request 事件,对本次请求,做一些响应处理* 3. 启动 Web 服务监听对应端口号* 4. 运行本服务在终端,用浏览器访问 http://localhost:3000/ 发起请求(localhost 是本机域名)* 注意:终端里启动了服务,如果想要终止按 ctrl c 停止即可*/
// 1. 引入 http 模块,创建 Web 服务对象
const http = require('http')
const server = http.createServer()
// 2. 监听 request 事件,对本次请求,做一些响应处理
server.on('request', (req, res) => {res.end('hello, world') // 一次请求只能对应一次响应
})
// 3. 启动 Web 服务监听对应端口号
server.listen(3000, () => {console.log('Web 服务启动了')
})
Web服务-支持中文字符
让 Web 服务,返回中文字符,浏览器正确解析加载
步骤:给 Web 服务程序添加响应头,设置内容类型和正确的编码格式,重启 Web 服务测试访问即可
res.setHeader('Content-Type', 'text/html;charset=utf-8')
- 编码:编码是信息从一种形式或格式转换为另一种形式的过程,指的把文字在计算机里的二进制数据,用什么形式展示出来
案例-省份列表接口
- 需求:基于 Web 服务,开发提供省份列表数据的接口,了解下后端的代码工作过程
- 步骤:
-
- 基于 http 模块,创建 Web 服务
-
- 使用 req.url 获取请求资源路径,并读取 province.json 理论省份数据返回给请求方
-
- 其他路径,暂时返回不存在的提示
-
- 运行 Web 服务,用浏览器发起请求测试,看是否可以获取到省份列表数据
- 代码如下:
["北京","天津","河北省","山西省","内蒙古自治区","辽宁省","吉林省","黑龙江省","上海","江苏省","浙江省","安徽省","福建省","江西省","山东省","河南省","湖北省","湖南省","广东省","广西壮族自治区","海南省","重庆","四川省","贵州省","云南省","西藏自治区","陕西省","甘肃省","青海省","宁夏回族自治区","新疆维吾尔自治区","台湾","香港特别行政区","澳门特别行政区"
]
/* 这个web服务提供的服务有:1. 当浏览器或者axios发送了 http://localhost:3000/api/province请求,就响应省份的json数据给客户端拆解流程:1. 准备一个json文件2. 准备一个web服务(http)3. request事件里面做出响应-> fs.readFile读取准备的json文件数据-> 设置响应头Content-Type-> res.end()响应
*/const { readFile } = require('fs')
const http = require('http')
const path = require('path')const server = http.createServer()server.on('request', (req, res) => {// 1. 如何判断客户端请求上来的路径地址是什么?// req.url存储的是请求的url的路径+参数// console.log(req.url)if (req.url == '/api/province') {// 2. 读取json文件内容响应readFile(path.join(__dirname,'/data/province.json'),(err,data)=>{if(err){res.end('接口500')}else{let jsonStr = data.toString()res.setHeader('Content-Type','application/json')res.end(jsonStr)}})}else{res.end('资源没有找到404')}
})server.listen(3000, () => {console.log('web服务已经启动,请使用http://localhost:3000来访问');
})
案例-城市列表接口
- 需求:基于刚刚的 Web 服务,开发提供城市列表数据的接口,了解下后端代码的工作过程
前置知识:字符串.startsWith() 和querystring模块
- 步骤:
-
- 判断 req.url 资源路径+查询字符串,路径前缀匹配 /api/city
-
- 借助 querystring 模块的方法,格式化查询字符串
-
- 读取 city.json 城市数据,匹配省份名字下属城市列表
-
- 返回城市列表,启动 Web 服务测试
- 代码如下:
{"北京": ["北京市"],"天津": ["天津市"],"河北省": ["石家庄市","唐山市","秦皇岛市","邯郸市","邢台市","保定市","张家口市","承德市","沧州市","廊坊市","衡水市"],"山西省": ["太原市","大同市","阳泉市","长治市","晋城市","朔州市","晋中市","运城市","忻州市","临汾市","吕梁市"],"内蒙古自治区": ["呼和浩特市","包头市","乌海市","赤峰市","通辽市","鄂尔多斯市","呼伦贝尔市","巴彦淖尔市","乌兰察布市","兴安盟","锡林郭勒盟","阿拉善盟"],"辽宁省": ["沈阳市","大连市","鞍山市","抚顺市","本溪市","丹东市","锦州市","营口市","阜新市","辽阳市","盘锦市","铁岭市","朝阳市","葫芦岛市"],"吉林省": ["长春市","吉林市","四平市","辽源市","通化市","白山市","松原市","白城市","延边朝鲜族自治州"],"黑龙江省": ["哈尔滨市","齐齐哈尔市","鸡西市","鹤岗市","双鸭山市","大庆市","伊春市","佳木斯市","七台河市","牡丹江市","黑河市","绥化市","大兴安岭地区"],"上海": ["上海市"],"江苏省": ["南京市","无锡市","徐州市","常州市","苏州市","南通市","连云港市","淮安市","盐城市","扬州市","镇江市","泰州市","宿迁市"],"浙江省": ["杭州市","宁波市","温州市","嘉兴市","湖州市","绍兴市","金华市","衢州市","舟山市","台州市","丽水市"],"安徽省": ["合肥市","芜湖市","蚌埠市","淮南市","马鞍山市","淮北市","铜陵市","安庆市","黄山市","滁州市","阜阳市","宿州市","巢湖市","六安市","亳州市","池州市","宣城市"],"福建省": ["福州市","厦门市","莆田市","三明市","泉州市","漳州市","南平市","龙岩市","宁德市"],"江西省": ["南昌市","景德镇市","萍乡市","九江市","新余市","鹰潭市","赣州市","吉安市","宜春市","抚州市","上饶市"],"山东省": ["济南市","青岛市","淄博市","枣庄市","东营市","烟台市","潍坊市","济宁市","泰安市","威海市","日照市","莱芜市","临沂市","德州市","聊城市","滨州市","菏泽市"],"河南省": ["郑州市","开封市","洛阳市","平顶山市","安阳市","鹤壁市","新乡市","焦作市","濮阳市","许昌市","漯河市","三门峡市","南阳市","商丘市","信阳市","周口市","驻马店市"],"湖北省": ["武汉市","黄石市","十堰市","宜昌市","襄阳市","鄂州市","荆门市","孝感市","荆州市","黄冈市","咸宁市","随州市","恩施土家族苗族自治州"],"湖南省": ["长沙市","株洲市","湘潭市","衡阳市","邵阳市","岳阳市","常德市","张家界市","益阳市","郴州市","永州市","怀化市","娄底市","湘西土家族苗族自治州"],"广东省": ["广州市","韶关市","深圳市","珠海市","汕头市","佛山市","江门市","湛江市","茂名市","肇庆市","惠州市","梅州市","汕尾市","河源市","阳江市","清远市","东莞市","中山市","潮州市","揭阳市","云浮市"],"广西壮族自治区": ["南宁市","柳州市","桂林市","梧州市","北海市","防城港市","钦州市","贵港市","玉林市","百色市","贺州市","河池市","来宾市","崇左市"],"海南省": ["海口市", "三亚市", "三沙市"],"重庆": ["重庆市"],"四川省": ["成都市","自贡市","攀枝花市","泸州市","德阳市","绵阳市","广元市","遂宁市","内江市","乐山市","南充市","眉山市","宜宾市","广安市","达州市","雅安市","巴中市","资阳市","阿坝藏族羌族自治州","甘孜藏族自治州","凉山彝族自治州"],"贵州省": ["贵阳市","六盘水市","遵义市","安顺市","铜仁市","黔西南布依族苗族自治州","毕节市","黔东南苗族侗族自治州","黔南布依族苗族自治州"],"云南省": ["昆明市","曲靖市","玉溪市","保山市","昭通市","丽江市","普洱市","临沧市","楚雄彝族自治州","红河哈尼族彝族自治州","文山壮族苗族自治州","西双版纳傣族自治州","大理白族自治州","德宏傣族景颇族自治州","怒江傈僳族自治州","迪庆藏族自治州"],"西藏自治区": ["拉萨市","昌都地区","山南地区","日喀则地区","那曲地区","阿里地区","林芝地区"],"陕西省": ["西安市","铜川市","宝鸡市","咸阳市","渭南市","延安市","汉中市","榆林市","安康市","商洛市"],"甘肃省": ["兰州市","嘉峪关市","金昌市","白银市","天水市","武威市","张掖市","平凉市","酒泉市","庆阳市","定西市","陇南市","临夏回族自治州","甘南藏族自治州"],"青海省": ["西宁市","海东市","海北藏族自治州","黄南藏族自治州","海南藏族自治州","果洛藏族自治州","玉树藏族自治州","海西蒙古族藏族自治州"],"宁夏回族自治区": ["银川市", "石嘴山市", "吴忠市", "固原市", "中卫市"],"新疆维吾尔自治区": ["乌鲁木齐市","克拉玛依市","吐鲁番地区","哈密地区","昌吉回族自治州","博尔塔拉蒙古自治州","巴音郭楞蒙古自治州","阿克苏地区","克孜勒苏柯尔克孜自治州","喀什地区","和田地区","伊犁哈萨克自治州","塔城地区","阿勒泰地区"],"台湾省": ["台北市","高雄市","台南市","台中市","金门县","南投县","基隆市","新竹市","嘉义市","新北市","宜兰县","新竹县","桃园县","苗栗县","彰化县","嘉义县","云林县","屏东县","台东县","花莲县","澎湖县","连江县"],"香港特别行政区": ["香港岛", "九龙", "新界"],"澳门特别行政区": ["澳门半岛", "离岛"]
}
/* 这个web服务提供的服务有:1. 当浏览器或者axios发送了 http://localhost:3000/api/province请求,就响应省份的json数据给客户端拆解流程:1. 准备一个json文件2. 准备一个web服务(http)3. request事件里面做出响应-> fs.readFile读取准备的json文件数据-> 设置响应头Content-Type-> res.end()响应
*/const { readFile } = require('fs')
const http = require('http')
const path = require('path')
const qs = require('querystring')const server = http.createServer()server.on('request', (req, res) => {// 1. 如何判断客户端请求上来的路径地址是什么?// req.url存储的是请求的url的路径+参数// console.log(req.url)if (req.url == '/api/province') {// 2. 读取json文件内容响应readFile(path.join(__dirname, '/data/province.json'), (err, data) => {if (err) {res.end('接口500')} else {let jsonStr = data.toString()res.setHeader('Content-Type', 'application/json')res.end(jsonStr)}})}else if (req.url.startsWith('/api/city')) {// 城市数据的提供// 1. 获取请求pname的值// req.url // /api/city?pname=辽宁省let queryString = req.url.split('?')[1] //pname=辽宁省const queryObj = qs.parse(queryString) // {pname:'辽宁省'}// console.log(queryObj.pname);// 2. 根据pname的值从city.json中获取指定的省份的城市响应readFile(path.join(__dirname, 'data/city.json'), (err, data) => {if (err) {res.end('500 server error')} else {// 字符串const cityJsonString = data.toString()// 必须将cityJsonString 转换js对象const cityObj = JSON.parse(cityJsonString)let cityArr = cityObj[queryObj.pname] // ['广州市','深圳市','''']res.setHeader('Content-Type', 'application/json;')res.end(JSON.stringify(cityArr))}})}else {res.end('资源没有找到404')}
})server.listen(3000, () => {console.log('web服务已经启动,请使用http://localhost:3000来访问');
})
案例-浏览时钟
- 需求:基于 Web 服务,开发提供网页资源的功能,了解下后端的代码工作过程
- 步骤:
-
- 基于 http 模块,创建 Web 服务
-
- 使用 req.url 获取请求资源路径为 /index.html 的时候,读取 index.html 文件内容字符串返回给请求方
-
- 其他路径,暂时返回不存在的提示
-
- 运行 Web 服务,用浏览器发起http://localhost:3000/index.html请求查看结果是否为倒计时页面
- 代码如下:
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>时钟案例</title> <style> html, body { margin: 0; padding: 0; height: 100%; background-image: linear-gradient(to bottom right, red, gold); } .box { width: 400px; height: 250px; background-color: rgba(255, 255, 255, 0.6); border-radius: 6px; position: absolute; left: 50%; top: 40%; transform: translate(-50%, -50%); box-shadow: 1px 1px 10px #fff; text-shadow: 0px 1px 30px white; display: flex; justify-content: space-around; align-items: center; font-size: 70px; user-select: none; padding: 0 20px; -webkit-box-reflect: below 0px -webkit-gradient(linear, left top, left bottom, from(transparent), color-stop(0%, transparent), to(rgba(250, 250, 250, .2))); } </style></head><body> <div class="box"> <div id="HH">00</div> <div>:</div> <div id="mm">00</div> <div>:</div> <div id="ss">00</div> </div></body></html><script>window.addEventListener('load', function () { clock(); setInterval(clock, 1000);});function clock() { let dt = new Date(); let HH = dt.getHours(); let mm = dt.getMinutes(); let ss = dt.getSeconds(); console.log(dt, HH, mm, ss); document.querySelector('#HH').innerHTML = padZero(HH); document.querySelector('#mm').innerHTML = padZero(mm); document.querySelector('#ss').innerHTML = padZero(ss);};function padZero(n) { return n > 9 ? n : '0' + n;}</script>
/*** 目标:编写 web 服务,监听请求的是 /index.html 路径的时候,返回 dist/index.html 时钟案例页面内容* 步骤:* 1. 基于 http 模块,创建 Web 服务* 2. 使用 req.url 获取请求资源路径,并读取 index.html 里字符串内容返回给请求方* 3. 其他路径,暂时返回不存在提示* 4. 运行 Web 服务,用浏览器发起请求*/
const fs = require('fs')
const path = require('path')
// 1. 基于 http 模块,创建 Web 服务
const http = require('http')
const server = http.createServer()
server.on('request', (req, res) => {// 2. 使用 req.url 获取请求资源路径,并读取 index.html 里字符串内容返回给请求方if (req.url === '/index.html') {fs.readFile(path.join(__dirname, 'dist/index.html'), (err, data) => {res.setHeader('Content-Type', 'text/html;charset=utf-8')res.end(data.toString())})} else {// 3. 其他路径,暂时返回不存在提示res.setHeader('Content-Type', 'text/html;charset=utf-8')res.end('你要访问的资源路径不存在')}
})
server.listen(8080, () => {console.log('Web 服务启动了')
})
今日作业(必完成)
tlias上发布
知识回顾
- node基本概念
-
- node是什么?-> node是一个执行js的环境
- node和浏览器有和相同点以及区别?
-
-
- 相同点:① node和浏览器都支持ECMAScript的标准语法 ② 都是V8引擎来解析js的
- 不同点:① node不支持DOM和BOM操作的 ② node本身提供的fs,path,http,request等这些模块浏览器是没有的
-
-
- node给前端做了哪些赋能?
-
-
- 可以让前端工程师做后端接口的开发(可以操作数据库,并且可以开启服务器 -> Web服务)
- 工程化(将来可以开发大型项目,让代码有良好的组织结构,维护很方便)
-
- 如何安装和配置node环境(提示)
-
- nvm来管理多个node版本之间的切换的
- 直接下载node安装包,双击安装
- 在开发目录中执行
npm install @types/node
就能具备node环境的提示功能
- 内置模块
-
- 引入一个node模块使用的关键字
require()
- fs -> 读写文件
- 引入一个node模块使用的关键字
-
-
- fs.readFile (异步方法)
- fs.writeFile (异步方法)
-
-
- path -> join()方法主要是用来拼接绝对路径
-
-
- __dirname -> 获取当前js文件所在的绝对路径
-
- http模块
-
- 基本网络知识
-
-
- 域名(IP)
- 端口
-
-
-
-
- 作用:是操作系统用来对外通讯的,需要我们编写web服务来监听这个端口,从而实现对外通讯
- 范围: 0 - 65535 ,总端口是是65536个
-
-
-
-
- 资源路径
- 查询参数
- http协议
-
-
-
-
- http请求协议 (约束客户端通过什么数据格式向服务器发送数据)
-
-
-
-
-
-
- 请求行
- 请求头
- 空白行
- 请求体
-
-
-
-
-
-
- http响应协议(约束服务器向客户端发送什么数据)
-
-
-
-
-
-
- 响应行
- 响应头 Content-Type -> 作用:告诉浏览器通过什么格式来解析我发给你的数据
-
-
-
-
-
-
-
-
- text/html
- application/json
-
-
-
-
-
-
-
-
- 空白行
- 响应体
-
-
-
-
- http模块的相关代码
-
-
- 开启一个web服务的核心步骤
-
const http = require('http')
const server = http.createServer()
server.on('request',(req,res)=>{
// 1. 如何向响应体中增加数据并结束响应res.end('响应体的数据')// 2. 如何设置响应头//key: Content-Type// value: text/html application/json// 告诉浏览器解析utf8格式的字符,需要使用 charset=utf-8res.setHeader('key','value')})server.listen(端口,()=>{// 成功开启web服务以后会自动执行这个回调函数
})
相关文章:
Node.js入门html,css,js 30年了nodejs环境 09年出现 15
Node.js入门 html,css,js 30年了 nodejs环境 09年出现 15年 nodejs为我们解决了2个方面的问题: 【锦上添花】让我们前端工程师拥有了后端开发能力(开接口,访问数据库) - 大公司BFF(50)【✔️】前端工程…...
2025跨年倒计时
<!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>2025年跨年倒计时</title><style>/* 页…...
淘宝京东电商商品SKU信息抓取API测试实战指南
在电商平台的商品管理中,SKU(Stock Keeping Unit,库存单位)信息扮演着至关重要的角色。它不仅关乎商品的库存管理,还直接影响到消费者的购买决策。为了高效地获取并验证电商平台(如淘宝、京东)上…...
SAP财务凭证的更改、冲销的方式
文章目录 一、财务凭证更改二、财务凭证冲销 【SAP系统研究】 #SAP #FICO #SAP财务 一、财务凭证更改 (1)已经过账的财务凭证 FB02:过完帐的允许更改的地方有限,只有凭证抬头文本、参照、分配、文本、原因代码等。 ࿰…...
RepPoints: Point Set Representation for Object Detection
CornerNet论文阅读整理-CSDN博客 可变形卷积(Deformable Conv)原理解析与torch代码实现-CSDN博客 RepPoints(本质是可变形卷积DCN)再理解-CSDN博客 简介: 时间:2019 会议:ICCV 作者:Ze Yang,Shaohui Liu,…...
高效使用AI完成编程项目任务的指南:从需求分析到功能实现
随着人工智能工具的普及,即便是零编程基础或基础薄弱的用户,也可以借助AI完成许多技术任务。然而,要高效地使用AI完成编程任务,关键在于如何清晰表达需求,并逐步引导AI实现目标。 在本文中,我们将通过开发…...
Linux命令——RPM与yum
文章目录 一、RPM包命令1.安装和升级包2.删除包3.查询包信息4.验证和检查5.其他操作 二、yum安装器1.安装包2.更新包3.卸载包4.查询和搜索5.清理缓存6.其他操作 一、RPM包命令 1.安装和升级包 命令解释rpm -ivh package.rpm安装一个 RPM 包,显示详细信息和进度条r…...
C++软件设计模式之责任链模式
责任链模式的动机与意图 动机: 在软件开发中,经常会遇到需要处理一系列请求或事件的情况。这些请求可能需要经过多个处理对象,每个对象根据其职责决定是否处理请求或将其传递给下一个对象。责任链模式(Chain of Responsibility P…...
Spring Cloud Security集成JWT 快速入门Demo
一、介绍 JWT (JSON Web Token) 是一种带有绑实和信息的简单标准化机制,在信息通信中用于验证和信息传递。尤其在应用中使用Spring Cloud实现分布式构建时,JWT可以作为一种无状态验证原理的证明。 本文将进一步描述如何在Spring Cloud Security中集成JW…...
Python 爬虫
一、创建项目 1.双击打开pycharm,点击新建项目 2.项目设置- 勾选[继承全局站点软件包]- 勾选[可用于所有项目]- 取消勾选[创建main.py欢迎脚本]- 点击创建 3.项目名称右键--新建--python文件 4.输入文件名--回车二、编辑代码 # 导入请求模块 import requests # 如…...
【PCIe 总线及设备入门学习专栏 4.1 -- PCI 总线的地址空间分配】
文章目录 Overview 本文转自:https://blog.chinaaet.com/justlxy/p/5100053219 Overview PCI 总线具有32位数据/地址复用总线,所以其存储地址空间为 2324GB。也就是PCI上的所有设备共同映射到这4GB上,每个PCI设备占用唯一的一段PCI地址&…...
虚拟电厂搭建指南:绿虫仿真设计软件的助力
在虚拟电厂的搭建中,绿虫仿真设计软件起着重要作用。 绿虫光伏仿真软件是一款综合性辅助工具,能为虚拟电厂中的光伏项目提供精准数据支持。它所提供的项目选址地气象数据,涵盖海拔、辐照、风速、温度等,数据源为 Meteonorm &…...
开源漏洞管理工具--Faraday
前言 在现代安全领域,面临着两个主要的挑战:一是设计出智能化的方式来获取新信息,二是有效地跟踪和管理发现的内容,以便不断改善修复工作。为了解决这些问题,Faraday应运而生,它能够帮助您专注于漏洞的发现…...
一、EF框架的Database First开发模式(数据库优先)
Database First开发模式(数据库优先) Database First是Entity Framework(EF)的三种开发模式之一,适用于在已有数据库的情况下进行开发。其核心思想是从现有数据库中逆向生成实体类和映射文件,然后在此基础上进行开发。 官方…...
Datawhale AI冬令营(第二期)动手学AI Agent task2--学Prompt工程,优化Agent效果
目录 如何写好Prompt? 工具包神器1:Prompt框架——CO-STAR 框架 工具包神器2:Prompt结构优化 工具包神器3:引入案例 案例:构建虚拟女友小冰 1. 按照 CO-STAR框架 梳理目标 2. 撰写Prompt 3. 制作对话生成应用&…...
Go IO之文件处理,TCPUDP讲解
文章目录 1 文件处理1.1 打开和关闭文件1.2 读取文件1.2.1 简单示例1.2.2 中文乱码1.2.2.1 bufio1.2.2.2 ioutil 1.3 写入文件1.3.1 Write 和 WriteString1.3.2 fmt.Fprintln1.3.2.1 写入文件1.3.2.2 写入标准输出 1.3.3 bufio.NewWriter1.3.4 ioutil.WriteFile 2 TCP&UDP2…...
[卫星遥感] 解密卫星目标跟踪:挑战与突破的深度剖析
目录 [卫星遥感] 解密卫星目标跟踪:挑战与突破的深度剖析 1. 卫星目标跟踪的核心挑战 1.1 目标的高速与不确定性 1.2 卫星传感器的局限性 1.3 数据处理与融合问题 1.4 大尺度与实时性要求 2. 当前卫星目标跟踪的主流技术 2.1 卡尔曼滤波(Kalman …...
U盘提示格式化?原因、恢复方案与预防措施全解析
一、U盘提示格式化现象概述 在日常使用U盘的过程中,我们有时会遇到一个令人头疼的问题——U盘插入电脑后,系统却弹出一个提示框,告知我们U盘需要格式化才能访问。这个提示往往伴随着数据的潜在丢失风险,让我们不禁为之心焦。U盘提…...
Vuex中dispatch的用法
在 Vuex 中,dispatch 是用于触发 actions 的方法,它的主要作用是调用一个 action 并可以传递一些参数。以下是关于 dispatch 的详细解释: 基本语法 dispatch(type, payload)type:要调用的 action 的名称,它是一个字符…...
Agent系列:AppAgent v2-屏幕智能Agent(详解版)
引言 简介 方法 Agent 框架 Agent 交互 探索阶段 部署阶段 文档生成 高级功能 实验结果 总结 局限性 未来工作 1. 引言 大语言模型(LLM)如 ChatGPT 和 GPT-4 显著提升了自然语言处理能力,并且推动了智能体在自主决策中的应用。…...
Word如何插入图片并移动到某个位置
Word如何插入图片并移动到某一个位置 新建word→插入→图片 选择合适的位置→选择图片→打开 点击图片→布局选项→选择文字环绕下的任意一个→固定在页面上 点击图片就可以将图片移动到任意位置...
[CTF/网络安全] 攻防世界 upload1 解题详析
姿势 在txt中写入一句话木马<?php eval($_POST[qiu]);?> 回显如下: 查看源代码: Array.prototype.contains function (obj) { var i this.length; while (i--) { if (this[i] obj) { return true; } } return false; } function …...
golang:微服务架构下的日志追踪系统(二)
背景 在使用Gin框架进行服务开发时,我们遇到了一个日志记录的问题。由于Gin的上下文(*gin.Context)实现了context.Context接口,在调用日志记录器的Info、Warn、Error等方法时,直接传递Gin的上下文通常不会导致编译错误…...
单片机的存储器类型
单片机(Microcontroller Unit, MCU)是一种将计算机的主要部分集成在一个芯片上的微型计算机。它集成了处理器(CPU)、存储器、输入输出接口等必要的功能模块,广泛应用于各种嵌入式系统中。单片机的存储器结构对于理解和使用单片机至关重要&…...
深入剖析MySQL数据库架构:核心组件、存储引擎与优化策略(一)
sql语句分为两大类:查询(select)、增删改----修改(update) select语句的执行流程 执行sql语句的流程:连接数据库、缓存查询、解析器、优化器、执行器、存储引擎操作数据 客户端:图形界面工具…...
java常见的面试题
目录 一、 spring的配置文件的哪四处? 1.数据源(Data Source)配置 2.事务管理器(Transaction Manager)配置 3. 扫描组件(Component Scanning)配置 4. AOP(面向切面编程)配置&…...
2025吉林大学软件学院研究生人工智能原理真题
选择题 5题共10分 5.以下模型不需要训练过程的是? A.支持向量机 B.决策树 C.KNN近邻算法 D.卷积神经网络 简答题 4题35分 1.大模型是否已经通过图灵测试 2.三个近二十年来的机器学习模型和应用案例 3.LDA原理和算法流程 4.CNN原理和算法流程 证明题 谓词逻辑15…...
Qt判别不同平台操作系统调用相应动态库读取RFID
本示例使用的读卡器:https://item.taobao.com/item.htm?spma21dvs.23580594.0.0.52de2c1b8jdyXi&ftt&id562957272162 #include <QDebug> #include "mainwindow.h" #include "./ui_mainwindow.h" #include "QLibrary"…...
智慧工地系统:建筑施工智能化管理的全新模式
智慧工地概述 智慧工地是将互联网的理念和和物联网的技术引入建筑工地,依托物联网、互联网、大数据、5G技术,建立云端数据平台,形成大数据的业务体系,打通一线操作与远程监管的链条,实现劳务、安全、环境、材料等各个…...
js将object整个实体对象作为参数传递
①将object实体转化成json字符串传递: JSON.stringify(obj) ②将json字符串转化成JSON对象值:JSON.parse(json) 实际应用: <div id"div_notice" stylefont-size:14px; width:100%; height:200px; overflow-y:auto;></di…...
shell的循环结构
1、思维导图 2、定义一个find函数,查找ubuntu和root的gid并使用变量接收结果 #!/bin/bash #第二题查找gid并返回结果 find() {u_gidid -g ubuntur_gidid -g rootecho "root-gid$r_gid"echo "ubuntu-gid$u_gid" } ret$(find) echo $ret3、定义一…...
STM32-笔记29-蓝牙遥控插座项目
一、实验前期准备 手机通过蓝牙模块远程遥控风扇。(插座的原理就是继电器,所以控制继电器就是控制插座电源) 二、项目实现 复制项目文件夹32-蓝牙模块实现,重命名33-蓝牙遥控插座项目 找到一个继电器项目,把继电器复…...
计算机网络复习(习题)
术语辨析 数据链路层 该层在两个通信实体之间传送以帧为单位的数据,通过差错控制方法,使有差错的物理线路变成无差错数据链路。 网络层 负责使分组以适当的路径通过通信子网的层次。 运输层 负责向两台主机中进程之间的通信提供通用的数据传输服务的层次。 应用层…...
webserver的http实现
1、用了状态机,为什么要用状态机? 在逻辑处理模块中,响应的http请求采用主从状态机完成, 传统的控制流程都是按照顺序执行的,状态机能够处理任意顺序的事件,并能提供有意义的响应--即使这些事件发生的顺序和…...
C语言----指针
目录 1.概念 2.格式 3.指针操作符 4.初始化 1. 将普通变量的地址赋值给指针变量 a. 将数组的首地址赋值给指针变量 b. 将指针变量里面保存的地址赋值给另一个指针变量 5.指针运算 5.1算术运算 5.2 关系运算 指针的大小 总结: 段错误 指针修饰 1. con…...
Elasticsearch与数据库数据一致性:最佳实践与解决方案
在现代应用程序中,Elasticsearch(ES)作为一个高效的分布式搜索引擎,常常与数据库一同使用,以提供强大的搜索、分析和数据可视化功能。然而,数据库和Elasticsearch之间的同步与一致性常常成为一个挑战。如何…...
C# 基本语法
C# 基本语法 介绍 C#(读作 "C sharp")是一种现代的、面向对象的编程语言,由微软开发,并在2000年首次发布。它是.NET框架的一部分,被广泛用于开发各种类型的应用程序,包括桌面应用、Web应用、移…...
CDGA|浅析自动化对数据治理的深远影响
在数字化时代,数据治理已成为企业管理的核心议题之一。随着数据量的快速增长和复杂性的不断提升,传统的手工数据管理方式已难以满足企业的需求。而自动化技术的引入,为数据治理带来了新的动力,正在逐步改变数据治理的面貌。 自动化…...
【机器学习】【朴素贝叶斯分类器】从理论到实践:朴素贝叶斯分类器在垃圾短信过滤中的应用
🌟 关于我 🌟 大家好呀!👋 我是一名大三在读学生,目前对人工智能领域充满了浓厚的兴趣,尤其是机器学习、深度学习和自然语言处理这些酷炫的技术!🤖💻 平时我喜欢动手做实…...
小程序租赁系统的优势与应用探索
内容概要 小程序租赁系统,听起来很高大上,但实际上它比你想象的要实用得多!设想一下,几乎所有的租赁需求都能通过手机轻松解决。这种系统的便捷性体现在让用户随时随地都能发起租赁请求,而不再受制于传统繁琐的手续。…...
汇编环境搭建
学习视频 将MASM所在目录 指定为C盘...
ubuntu24.04使用open-vm-tools无法在主机和虚拟机之间拖拽文件夹
最近安装了vmware用ubuntu24.04作为虚拟机 然后发现无法在主机和虚拟机之间复制粘贴 然后安装了 sudo apt-get install open-vm-tools-desktop重启虚拟机,发现可以复制粘贴文字,但是文件和文件夹仍然不行 搜索发现是Ubuntu(22.04࿰…...
C++软件设计模式之模板方法模式
模板方法模式是面向对象软件设计模式之一,其主要意图是在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中实现。模板方法使得子类可以在不改变算法结构的情况下重新定义算法的某些特定步骤。 动机 在软件开发中,常常会遇到这样的情…...
20241231 机器学习ML -(2)KNN(scikitlearn)
1. build DKTree 递推创建Tree;当前维度找中位数分割 数据集 left set,Node(mid), right set. * 循环维度(当log(Nsample)>featureSize) 2. DKTree KNN search * 理论部分向量几何有介绍。 每个维度列中,中位数对应的数据点…...
Prometheus之终极指南(The Ultimate Guide to Prometheus)
Prometheus之终极指南 Prometheus 彻底改变了我们在现代 DevOps 生态系统中监控基础设施、应用程序和服务的方式。它不仅仅是一个工具;它是一个由指标收集、告警和实时监控组成的生态系统,受到 Uber、Google 和 SoundCloud 等组织的信任。在本文中&…...
如何使用Python调用淘宝api接口获取商品详情信息?
使用 Python 调用淘宝 API 接口获取商品详情信息,可按照以下步骤进行: 注册并获取 API 密钥 访问淘宝api文档,点击 “立即测试” 按钮,按照提示完成注册流程。注册成功后,登录测试平台,进入 “控制台” 页面…...
ubuntu 22下解决Unment dependencies问题
问题现象 在使用apt安装包的时候,出现如下错误: 解决方案 第一步 sudo apt-get -f install sudo apt-get update sudo apt-get upgrade第二步 sudo apt-get update sudo apt-get clean sudo apt-get autoremove第三步 sudo apt --fix-broken inst…...
leetcode 热题100(155. 最小栈)multiset c++
链接:155. 最小栈 - 力扣(LeetCode) 设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。 实现 MinStack 类: MinStack() 初始化堆栈对象。void push(int val) 将元素val推入堆栈。…...
某小程序sign签名参数逆向分析
文章目录 1. 写在前面2. 接口分析3. 分析还原 【🏠作者主页】:吴秋霖 【💼作者介绍】:擅长爬虫与JS加密逆向分析!Python领域优质创作者、CSDN博客专家、阿里云博客专家、华为云享专家。一路走来长期坚守并致力于Python…...
阿里云redis内存优化——PCP数据清理
在阿里云安装了一个redis节点,今天使用时忽然想着点击了一下分析内存。好家伙,居然崩出了一个30多M的块出来。问题是我本地安装的redis没有这个啊,怎么奇怪冒出这个来了。 本着把系统用干榨尽的态度,研究了下这个问题的来源。网上…...