深入浅出Node.js-1(node.js入门)

打印 上一主题 下一主题

主题 1023|帖子 1023|积分 3069



全新专栏带你快速把握node.js

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(指定版本:为了兼容后期学习的项目)
  1. # ✨安装node 16.19.0版本
  2. nvm install 16.19.0
  3. # ✨查看node版本列表(带*号的表示当前使用的版本)
  4. nvm ls
  5. # ✨切换node版本
  6. 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 文件路径
  1. console.log('Hello, World')
  2. for (let i = 0; i < 3; i++) {
  3.   console.log('☆')
  4. }
复制代码
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 对象
  1. const fs = require('fs')
复制代码
写入文件内容语法:
  1. fs.writeFile('文件路径', '写入内容', err => {
  2.   // 写入后的回调函数
  3. })
复制代码
读取文件内容的语法:
  1. fs.readFile('文件路径', (err, data) => {
  2.   // 读取后的回调函数
  3.   // data 是文件内容的 Buffer 数据流
  4. })
复制代码

  • 需求:向 test.txt 文件写入内容并读取打印
  1. /**
  2. * 目标:使用 fs 模块,读写文件内容
  3. * 语法:
  4. * 1. 引入 fs 模块
  5. * 2. 调用 writeFile 写入内容
  6. * 3. 调用 readFile  读取内容
  7. */
  8. // 1. 引入 fs 模块
  9. const fs = require('fs')
  10. // 2. 调用 writeFile 写入内容
  11. // 注意:建议写入字符串内容,会覆盖目标文件所有内容
  12. fs.writeFile('./text.txt', '欢迎使用 fs 模块读写文件内容', err => {
  13.   if (err) console.log(err)
  14.   else console.log('写入成功')
  15. })
  16. // 3. 调用 readFile  读取内容
  17. fs.readFile('./text.txt', (err, data) => {
  18.   if (err) console.log(err)
  19.   else console.log(data.toString()) // 把 Buffer 数据流转成字符串类型
  20. })
复制代码
path模块-路径处理


  • 为什么在 Node.js 待执行的 JS 代码中要用绝对路径:
Node.js 执行 JS 代码时,代码中的路径都是以终端所在文件夹出发查找相对路径,而不是以我们认为的从代码本身出发,会碰到题目,所以在 Node.js 要执行的代码中,访问其他文件,建议使用绝对路径

  • 新建 03 文件夹编写待执行的 JS 代码,访问外层相对路径下的文件,然后在最外层终端路径来执行目的文件,造成题目




  • 题目原因:就是从代码文件夹出发,使用../text.txt剖析路径,找不到目的文件,报错了!

  • 解决方案:使用模块内置变量 __dirname配合 path.join() 来得到绝对路径使用
  1. const fs = require('fs')
  2. console.log(__dirname) // D:\备课代码\2_node_3天\Node_代码\Day01_Node.js入门\代码\03
  3. // 1. 加载 path 模块
  4. const path = require('path')
  5. // 2. 使用 path.join() 来拼接路径
  6. const pathStr = path.join(__dirname, '..', 'text.txt')
  7. console.log(pathStr)
  8. fs.readFile(pathStr, (err, data) => {
  9.   if (err) console.log(err)
  10.   else console.log(data.toString())
  11. })
复制代码

  • 再次执行查看题目就被修复了!以后在 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中 完成代码压缩
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.   <meta charset="UTF-8">
  5.   <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6.   <meta http-equiv="X-UA-Compatible" content="ie=edge">
  7.   <title>时钟案例</title>
  8.   <style>
  9.     html,
  10.     body {
  11.       margin: 0;
  12.       padding: 0;
  13.       height: 100%;
  14.       background-image: linear-gradient(to bottom right, red, gold);
  15.     }
  16.     .box {
  17.       width: 400px;
  18.       height: 250px;
  19.       background-color: rgba(255, 255, 255, 0.6);
  20.       border-radius: 6px;
  21.       position: absolute;
  22.       left: 50%;
  23.       top: 40%;
  24.       transform: translate(-50%, -50%);
  25.       box-shadow: 1px 1px 10px #fff;
  26.       text-shadow: 0px 1px 30px white;
  27.       display: flex;
  28.       justify-content: space-around;
  29.       align-items: center;
  30.       font-size: 70px;
  31.       user-select: none;
  32.       padding: 0 20px;
  33.       -webkit-box-reflect: below 0px -webkit-gradient(linear, left top, left bottom, from(transparent), color-stop(0%, transparent), to(rgba(250, 250, 250, .2)));
  34.     }
  35.   </style>
  36. </head>
  37. <body>
  38.   <div class="box">
  39.     <div id="HH">00</div>
  40.     <div>:</div>
  41.     <div id="mm">00</div>
  42.     <div>:</div>
  43.     <div id="ss">00</div>
  44.   </div>
  45. </body>
  46. </html>
复制代码
  1. /*
  2.   职责:将 public/index.html压缩
  3.   代码:
  4. 1.使用fs.readFile读取public\index.html中的内容
  5. 2.正则替换index.html中字符串/rn]/g
  6. 3.将替换后的新内容写入到新dist\index.html中完成代码压缩
  7. */
  8. const { readFile,writeFile } = require("fs");
  9. const path = require("path");
  10. // 1. 读取未压缩的index.html内容
  11. let indexPath = path.join(__dirname, 'public/index.html')
  12. readFile(indexPath, (err, data) => {
  13.     if (err) {
  14.         console.log(err);
  15.     } else {
  16.         // console.log(data.toString())
  17.         let unzipHtml = data.toString()
  18.         // 2.正则替换index.html中字符串/rn]/g
  19.         const reg = /[\r\n]/g
  20.         const zipHtml = unzipHtml.replace(reg, '')
  21.         // console.log(zipHtml)
  22.         // 3.将替换后的新内容写入到新dist\index.html中完成代码压缩
  23.         let targetPath = path.join(__dirname, 'dist/index.html')
  24.         writeFile(targetPath,zipHtml,(err)=>{
  25.             if(err){
  26.                 console.log(err);               
  27.             }else{
  28.                 console.log('写入成功');
  29.                
  30.             }
  31.         })
  32.         
  33.     }
  34. })
复制代码

案例-压缩前端JS

需求:把准备好的 JS 文件代码的回车符,换行符,打印语句去掉,并插入到之前 html 内容之后
步骤:

  • 读取 public/index.js 内容
  • 使用正则更换内容字符串里的\r \n 和console.log('xxx')


    • /[\r\n]/g
    • /console.log\('.+?'\);/g


  • 拼接 html 内容写入到 dist/index.html 内
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.   <meta charset="UTF-8">
  5.   <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6.   <meta http-equiv="X-UA-Compatible" content="ie=edge">
  7.   <title>时钟案例</title>
  8.   <style>
  9.     html,
  10.     body {
  11.       margin: 0;
  12.       padding: 0;
  13.       height: 100%;
  14.       background-image: linear-gradient(to bottom right, red, gold);
  15.     }
  16.     .box {
  17.       width: 400px;
  18.       height: 250px;
  19.       background-color: rgba(255, 255, 255, 0.6);
  20.       border-radius: 6px;
  21.       position: absolute;
  22.       left: 50%;
  23.       top: 40%;
  24.       transform: translate(-50%, -50%);
  25.       box-shadow: 1px 1px 10px #fff;
  26.       text-shadow: 0px 1px 30px white;
  27.       display: flex;
  28.       justify-content: space-around;
  29.       align-items: center;
  30.       font-size: 70px;
  31.       user-select: none;
  32.       padding: 0 20px;
  33.       -webkit-box-reflect: below 0px -webkit-gradient(linear, left top, left bottom, from(transparent), color-stop(0%, transparent), to(rgba(250, 250, 250, .2)));
  34.     }
  35.   </style>
  36. </head>
  37. <body>
  38.   <div class="box">
  39.     <div id="HH">00</div>
  40.     <div>:</div>
  41.     <div id="mm">00</div>
  42.     <div>:</div>
  43.     <div id="ss">00</div>
  44.   </div>
  45. </body>
  46. </html>
复制代码
  1. window.addEventListener('load', function () {
  2.   console.log('测试-网页加载完成了');
  3.   clock();
  4.   setInterval(clock, 1000);
  5. });
  6. function clock() {
  7.   console.log('测试-时钟函数调用了');
  8.   let dt = new Date();
  9.   let HH = dt.getHours();
  10.   let mm = dt.getMinutes();
  11.   let ss = dt.getSeconds();
  12.   console.log(dt, HH, mm, ss);
  13.   document.querySelector('#HH').innerHTML = padZero(HH);
  14.   document.querySelector('#mm').innerHTML = padZero(mm);
  15.   document.querySelector('#ss').innerHTML = padZero(ss);
  16. };
  17. function padZero(n) {
  18.   console.log('时间测试');
  19.   return n > 9 ? n : '0' + n;
  20. }
复制代码
  1. /**
  2. * 目标二:压缩 js 里代码,并整合到 html 中一起运行
  3. *  2.1 读取 public/index.js 内容
  4. *  2.2 使用正则替换内容字符串里的,回车符\r 换行符\n 打印语句console.log('xxx');
  5. *  2.3 确认后,拼接 html 内容写入到 dist/index.html 内
  6. */
  7. const fs = require('fs')
  8. const path = require('path')
  9. fs.readFile(path.join(__dirname, 'public', 'index.html'), (err, data) => {
  10.   const htmlStr = data.toString()
  11.   const resultStr = htmlStr.replace(/[\r\n]/g, '')
  12.   // 2.1 读取 public/index.js 内容
  13.   fs.readFile(path.join(__dirname, 'public', 'index.js'), (err, data) => {
  14.     const jsStr = data.toString()
  15.     // 2.2 使用正则替换内容字符串里的,回车符\r 换行符\n 打印语句console.log('xxx');
  16.     const jsResultStr = jsStr.replace(/[\r\n]/g, '').replace(/console.log\('.+?'\);/g, '')
  17.     const result = `<script>${jsResultStr}</script>`
  18.     console.log(result)
  19.     // 2.3 确认后,拼接 html 内容写入到 dist/index.html 内
  20.     fs.writeFile(path.join(__dirname, 'dist', 'index.html'), resultStr + result, err => {
  21.       if (err) console.log(err)
  22.       else console.log('压缩成功')
  23.     })
  24.   })
  25. })
复制代码

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
  • 一个端口只能有一个服务监听,如果前一个服务器未关闭,则第二次启动会报错
  1. /**
  2. * 目标:使用 http 模块,创建 Web 服务
  3. * Web服务:一个程序,用于提供网上信息浏览服务
  4. * 步骤:
  5. *  1. 引入 http 模块,创建 Web 服务对象
  6. *  2. 监听 request 事件,对本次请求,做一些响应处理
  7. *  3. 启动 Web 服务监听对应端口号
  8. *  4. 运行本服务在终端,用浏览器访问 http://localhost:3000/ 发起请求(localhost 是本机域名)
  9. * 注意:终端里启动了服务,如果想要终止按 ctrl c 停止即可
  10. */
  11. // 1. 引入 http 模块,创建 Web 服务对象
  12. const http = require('http')
  13. const server = http.createServer()
  14. // 2. 监听 request 事件,对本次请求,做一些响应处理
  15. server.on('request', (req, res) => {
  16.   res.end('hello, world') // 一次请求只能对应一次响应
  17. })
  18. // 3. 启动 Web 服务监听对应端口号
  19. server.listen(3000, () => {
  20.   console.log('Web 服务启动了')
  21. })
复制代码

Web服务-支持中笔墨符

让 Web 服务,返回中笔墨符,欣赏器正确剖析加载
步骤:给 Web 服务步伐添加响应头,设置内容类型和正确的编码格式,重启 Web 服务测试访问即可
  1. res.setHeader('Content-Type', 'text/html;charset=utf-8')
复制代码

  • 编码:编码是信息从一种形式或格式转换为另一种形式的过程,指的把笔墨在盘算机里的二进制数据,用什么形式展示出来
案例-省份列表接口


  • 需求:基于 Web 服务,开发提供省份列表数据的接口,了解下后端的代码工作过程



  • 步骤:


    • 基于 http 模块,创建 Web 服务



    • 使用 req.url 获取请求资源路径,并读取 province.json 理论省份数据返回给请求方



    • 其他路径,临时返回不存在的提示



    • 运行 Web 服务,用欣赏器发起请求测试,看是否可以获取到省份列表数据


  • 代码如下:
  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. ]
复制代码
  1. /*
  2.   这个web服务提供的服务有:
  3.   1. 当浏览器或者axios发送了 http://localhost:3000/api/province请求,就响应省份的json数据给客户端
  4.   拆解流程:
  5.   1. 准备一个json文件
  6.   2. 准备一个web服务(http)
  7.   3. request事件里面做出响应
  8.     -> fs.readFile读取准备的json文件数据
  9.     -> 设置响应头Content-Type
  10.     -> res.end()响应
  11. */
  12. const { readFile } = require('fs')
  13. const http = require('http')
  14. const path = require('path')
  15. const server = http.createServer()
  16. server.on('request', (req, res) => {
  17.     // 1. 如何判断客户端请求上来的路径地址是什么?
  18.     // req.url存储的是请求的url的路径+参数
  19.     //    console.log(req.url)
  20.     if (req.url == '/api/province') {
  21.         // 2. 读取json文件内容响应
  22.         readFile(path.join(__dirname,'/data/province.json'),(err,data)=>{
  23.             if(err){
  24.                 res.end('接口500')
  25.             }else{
  26.                 let jsonStr = data.toString()
  27.                 res.setHeader('Content-Type','application/json')
  28.                 res.end(jsonStr)
  29.             }
  30.         })
  31.     }else{
  32.         res.end('资源没有找到404')
  33.     }   
  34. })
  35. server.listen(3000, () => {
  36.     console.log('web服务已经启动,请使用http://localhost:3000来访问');
  37. })
复制代码
案例-城市列表接口


  • 需求:基于刚刚的 Web 服务,开发提供城市列表数据的接口,了解下后端代码的工作过程


前置知识:字符串.startsWith() 和querystring模块





  • 步骤:


    • 判断 req.url 资源路径+查询字符串,路径前缀匹配 /api/city



    • 借助 querystring 模块的方法,格式化查询字符串



    • 读取 city.json 城市数据,匹配省份名字部属城市列表



    • 返回城市列表,启动 Web 服务测试


  • 代码如下:
  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.     "朝阳市",
  58.     "葫芦岛市"
  59.   ],
  60.   "吉林省": [
  61.     "长春市",
  62.     "吉林市",
  63.     "四平市",
  64.     "辽源市",
  65.     "通化市",
  66.     "白山市",
  67.     "松原市",
  68.     "白城市",
  69.     "延边朝鲜族自治州"
  70.   ],
  71.   "黑龙江省": [
  72.     "哈尔滨市",
  73.     "齐齐哈尔市",
  74.     "鸡西市",
  75.     "鹤岗市",
  76.     "双鸭山市",
  77.     "大庆市",
  78.     "伊春市",
  79.     "佳木斯市",
  80.     "七台河市",
  81.     "牡丹江市",
  82.     "黑河市",
  83.     "绥化市",
  84.     "大兴安岭地区"
  85.   ],
  86.   "上海": ["上海市"],
  87.   "江苏省": [
  88.     "南京市",
  89.     "无锡市",
  90.     "徐州市",
  91.     "常州市",
  92.     "苏州市",
  93.     "南通市",
  94.     "连云港市",
  95.     "淮安市",
  96.     "盐城市",
  97.     "扬州市",
  98.     "镇江市",
  99.     "泰州市",
  100.     "宿迁市"
  101.   ],
  102.   "浙江省": [
  103.     "杭州市",
  104.     "宁波市",
  105.     "温州市",
  106.     "嘉兴市",
  107.     "湖州市",
  108.     "绍兴市",
  109.     "金华市",
  110.     "衢州市",
  111.     "舟山市",
  112.     "台州市",
  113.     "丽水市"
  114.   ],
  115.   "安徽省": [
  116.     "合肥市",
  117.     "芜湖市",
  118.     "蚌埠市",
  119.     "淮南市",
  120.     "马鞍山市",
  121.     "淮北市",
  122.     "铜陵市",
  123.     "安庆市",
  124.     "黄山市",
  125.     "滁州市",
  126.     "阜阳市",
  127.     "宿州市",
  128.     "巢湖市",
  129.     "六安市",
  130.     "亳州市",
  131.     "池州市",
  132.     "宣城市"
  133.   ],
  134.   "福建省": [
  135.     "福州市",
  136.     "厦门市",
  137.     "莆田市",
  138.     "三明市",
  139.     "泉州市",
  140.     "漳州市",
  141.     "南平市",
  142.     "龙岩市",
  143.     "宁德市"
  144.   ],
  145.   "江西省": [
  146.     "南昌市",
  147.     "景德镇市",
  148.     "萍乡市",
  149.     "九江市",
  150.     "新余市",
  151.     "鹰潭市",
  152.     "赣州市",
  153.     "吉安市",
  154.     "宜春市",
  155.     "抚州市",
  156.     "上饶市"
  157.   ],
  158.   "山东省": [
  159.     "济南市",
  160.     "青岛市",
  161.     "淄博市",
  162.     "枣庄市",
  163.     "东营市",
  164.     "烟台市",
  165.     "潍坊市",
  166.     "济宁市",
  167.     "泰安市",
  168.     "威海市",
  169.     "日照市",
  170.     "莱芜市",
  171.     "临沂市",
  172.     "德州市",
  173.     "聊城市",
  174.     "滨州市",
  175.     "菏泽市"
  176.   ],
  177.   "河南省": [
  178.     "郑州市",
  179.     "开封市",
  180.     "洛阳市",
  181.     "平顶山市",
  182.     "安阳市",
  183.     "鹤壁市",
  184.     "新乡市",
  185.     "焦作市",
  186.     "濮阳市",
  187.     "许昌市",
  188.     "漯河市",
  189.     "三门峡市",
  190.     "南阳市",
  191.     "商丘市",
  192.     "信阳市",
  193.     "周口市",
  194.     "驻马店市"
  195.   ],
  196.   "湖北省": [
  197.     "武汉市",
  198.     "黄石市",
  199.     "十堰市",
  200.     "宜昌市",
  201.     "襄阳市",
  202.     "鄂州市",
  203.     "荆门市",
  204.     "孝感市",
  205.     "荆州市",
  206.     "黄冈市",
  207.     "咸宁市",
  208.     "随州市",
  209.     "恩施土家族苗族自治州"
  210.   ],
  211.   "湖南省": [
  212.     "长沙市",
  213.     "株洲市",
  214.     "湘潭市",
  215.     "衡阳市",
  216.     "邵阳市",
  217.     "岳阳市",
  218.     "常德市",
  219.     "张家界市",
  220.     "益阳市",
  221.     "郴州市",
  222.     "永州市",
  223.     "怀化市",
  224.     "娄底市",
  225.     "湘西土家族苗族自治州"
  226.   ],
  227.   "广东省": [
  228.     "广州市",
  229.     "韶关市",
  230.     "深圳市",
  231.     "珠海市",
  232.     "汕头市",
  233.     "佛山市",
  234.     "江门市",
  235.     "湛江市",
  236.     "茂名市",
  237.     "肇庆市",
  238.     "惠州市",
  239.     "梅州市",
  240.     "汕尾市",
  241.     "河源市",
  242.     "阳江市",
  243.     "清远市",
  244.     "东莞市",
  245.     "中山市",
  246.     "潮州市",
  247.     "揭阳市",
  248.     "云浮市"
  249.   ],
  250.   "广西壮族自治区": [
  251.     "南宁市",
  252.     "柳州市",
  253.     "桂林市",
  254.     "梧州市",
  255.     "北海市",
  256.     "防城港市",
  257.     "钦州市",
  258.     "贵港市",
  259.     "玉林市",
  260.     "百色市",
  261.     "贺州市",
  262.     "河池市",
  263.     "来宾市",
  264.     "崇左市"
  265.   ],
  266.   "海南省": ["海口市", "三亚市", "三沙市"],
  267.   "重庆": ["重庆市"],
  268.   "四川省": [
  269.     "成都市",
  270.     "自贡市",
  271.     "攀枝花市",
  272.     "泸州市",
  273.     "德阳市",
  274.     "绵阳市",
  275.     "广元市",
  276.     "遂宁市",
  277.     "内江市",
  278.     "乐山市",
  279.     "南充市",
  280.     "眉山市",
  281.     "宜宾市",
  282.     "广安市",
  283.     "达州市",
  284.     "雅安市",
  285.     "巴中市",
  286.     "资阳市",
  287.     "阿坝藏族羌族自治州",
  288.     "甘孜藏族自治州",
  289.     "凉山彝族自治州"
  290.   ],
  291.   "贵州省": [
  292.     "贵阳市",
  293.     "六盘水市",
  294.     "遵义市",
  295.     "安顺市",
  296.     "铜仁市",
  297.     "黔西南布依族苗族自治州",
  298.     "毕节市",
  299.     "黔东南苗族侗族自治州",
  300.     "黔南布依族苗族自治州"
  301.   ],
  302.   "云南省": [
  303.     "昆明市",
  304.     "曲靖市",
  305.     "玉溪市",
  306.     "保山市",
  307.     "昭通市",
  308.     "丽江市",
  309.     "普洱市",
  310.     "临沧市",
  311.     "楚雄彝族自治州",
  312.     "红河哈尼族彝族自治州",
  313.     "文山壮族苗族自治州",
  314.     "西双版纳傣族自治州",
  315.     "大理白族自治州",
  316.     "德宏傣族景颇族自治州",
  317.     "怒江傈僳族自治州",
  318.     "迪庆藏族自治州"
  319.   ],
  320.   "西藏自治区": [
  321.     "拉萨市",
  322.     "昌都地区",
  323.     "山南地区",
  324.     "日喀则地区",
  325.     "那曲地区",
  326.     "阿里地区",
  327.     "林芝地区"
  328.   ],
  329.   "陕西省": [
  330.     "西安市",
  331.     "铜川市",
  332.     "宝鸡市",
  333.     "咸阳市",
  334.     "渭南市",
  335.     "延安市",
  336.     "汉中市",
  337.     "榆林市",
  338.     "安康市",
  339.     "商洛市"
  340.   ],
  341.   "甘肃省": [
  342.     "兰州市",
  343.     "嘉峪关市",
  344.     "金昌市",
  345.     "白银市",
  346.     "天水市",
  347.     "武威市",
  348.     "张掖市",
  349.     "平凉市",
  350.     "酒泉市",
  351.     "庆阳市",
  352.     "定西市",
  353.     "陇南市",
  354.     "临夏回族自治州",
  355.     "甘南藏族自治州"
  356.   ],
  357.   "青海省": [
  358.     "西宁市",
  359.     "海东市",
  360.     "海北藏族自治州",
  361.     "黄南藏族自治州",
  362.     "海南藏族自治州",
  363.     "果洛藏族自治州",
  364.     "玉树藏族自治州",
  365.     "海西蒙古族藏族自治州"
  366.   ],
  367.   "宁夏回族自治区": ["银川市", "石嘴山市", "吴忠市", "固原市", "中卫市"],
  368.   "新疆维吾尔自治区": [
  369.     "乌鲁木齐市",
  370.     "克拉玛依市",
  371.     "吐鲁番地区",
  372.     "哈密地区",
  373.     "昌吉回族自治州",
  374.     "博尔塔拉蒙古自治州",
  375.     "巴音郭楞蒙古自治州",
  376.     "阿克苏地区",
  377.     "克孜勒苏柯尔克孜自治州",
  378.     "喀什地区",
  379.     "和田地区",
  380.     "伊犁哈萨克自治州",
  381.     "塔城地区",
  382.     "阿勒泰地区"
  383.   ],
  384.   "台湾省": [
  385.     "台北市",
  386.     "高雄市",
  387.     "台南市",
  388.     "台中市",
  389.     "金门县",
  390.     "南投县",
  391.     "基隆市",
  392.     "新竹市",
  393.     "嘉义市",
  394.     "新北市",
  395.     "宜兰县",
  396.     "新竹县",
  397.     "桃园县",
  398.     "苗栗县",
  399.     "彰化县",
  400.     "嘉义县",
  401.     "云林县",
  402.     "屏东县",
  403.     "台东县",
  404.     "花莲县",
  405.     "澎湖县",
  406.     "连江县"
  407.   ],
  408.   "香港特别行政区": ["香港岛", "九龙", "新界"],
  409.   "澳门特别行政区": ["澳门半岛", "离岛"]
  410. }
复制代码
  1. /*
  2.   这个web服务提供的服务有:
  3.   1. 当浏览器或者axios发送了 http://localhost:3000/api/province请求,就响应省份的json数据给客户端
  4.   拆解流程:
  5.   1. 准备一个json文件
  6.   2. 准备一个web服务(http)
  7.   3. request事件里面做出响应
  8.     -> fs.readFile读取准备的json文件数据
  9.     -> 设置响应头Content-Type
  10.     -> res.end()响应
  11. */
  12. const { readFile } = require('fs')
  13. const http = require('http')
  14. const path = require('path')
  15. const qs = require('querystring')
  16. const server = http.createServer()
  17. server.on('request', (req, res) => {
  18.     // 1. 如何判断客户端请求上来的路径地址是什么?
  19.     // req.url存储的是请求的url的路径+参数
  20.     //    console.log(req.url)
  21.     if (req.url == '/api/province') {
  22.         // 2. 读取json文件内容响应
  23.         readFile(path.join(__dirname, '/data/province.json'), (err, data) => {
  24.             if (err) {
  25.                 res.end('接口500')
  26.             } else {
  27.                 let jsonStr = data.toString()
  28.                 res.setHeader('Content-Type', 'application/json')
  29.                 res.end(jsonStr)
  30.             }
  31.         })
  32.     }
  33.     else if (req.url.startsWith('/api/city')) {
  34.         // 城市数据的提供
  35.         // 1. 获取请求pname的值
  36.         // req.url  // /api/city?pname=辽宁省
  37.         let queryString = req.url.split('?')[1]  //pname=辽宁省
  38.         const queryObj = qs.parse(queryString)  // {pname:'辽宁省'}
  39.         // console.log(queryObj.pname);
  40.         // 2. 根据pname的值从city.json中获取指定的省份的城市响应
  41.         readFile(path.join(__dirname, 'data/city.json'), (err, data) => {
  42.             if (err) {
  43.                 res.end('500 server error')
  44.             } else {
  45.                 // 字符串
  46.                 const cityJsonString = data.toString()
  47.                 // 必须将cityJsonString 转换js对象
  48.                 const cityObj = JSON.parse(cityJsonString)
  49.                 let cityArr = cityObj[queryObj.pname] // ['广州市','深圳市','''']
  50.                 res.setHeader('Content-Type', 'application/json;')
  51.                 res.end(JSON.stringify(cityArr))
  52.             }
  53.         })
  54.     }
  55.     else {
  56.         res.end('资源没有找到404')
  57.     }
  58. })
  59. server.listen(3000, () => {
  60.     console.log('web服务已经启动,请使用http://localhost:3000来访问');
  61. })
复制代码
案例-欣赏时钟


  • 需求:基于 Web 服务,开发提供网页资源的功能,了解下后端的代码工作过程



  • 步骤:


    • 基于 http 模块,创建 Web 服务



    • 使用 req.url 获取请求资源路径为 /index.html 的时候,读取 index.html 文件内容字符串返回给请求方



    • 其他路径,临时返回不存在的提示



    • 运行 Web 服务,用欣赏器发起http://localhost:3000/index.html请求查看效果是否为倒计时页面


  • 代码如下:
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.   <meta charset="UTF-8">
  5.   <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6.   <meta http-equiv="X-UA-Compatible" content="ie=edge">
  7.   <title>时钟案例</title>
  8.   <style>
  9.     html,
  10.     body {
  11.       margin: 0;
  12.       padding: 0;
  13.       height: 100%;
  14.       background-image: linear-gradient(to bottom right, red, gold);
  15.     }
  16.     .box {
  17.       width: 400px;
  18.       height: 250px;
  19.       background-color: rgba(255, 255, 255, 0.6);
  20.       border-radius: 6px;
  21.       position: absolute;
  22.       left: 50%;
  23.       top: 40%;
  24.       transform: translate(-50%, -50%);
  25.       box-shadow: 1px 1px 10px #fff;
  26.       text-shadow: 0px 1px 30px white;
  27.       display: flex;
  28.       justify-content: space-around;
  29.       align-items: center;
  30.       font-size: 70px;
  31.       user-select: none;
  32.       padding: 0 20px;
  33.       -webkit-box-reflect: below 0px -webkit-gradient(linear, left top, left bottom, from(transparent), color-stop(0%, transparent), to(rgba(250, 250, 250, .2)));
  34.     }
  35.   </style>
  36. </head>
  37. <body>
  38.   <div class="box">
  39.     <div id="HH">00</div>
  40.     <div>:</div>
  41.     <div id="mm">00</div>
  42.     <div>:</div>
  43.     <div id="ss">00</div>
  44.   </div>
  45. </body>
  46. </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>
复制代码
  1. /**
  2. * 目标:编写 web 服务,监听请求的是 /index.html 路径的时候,返回 dist/index.html 时钟案例页面内容
  3. * 步骤:
  4. *  1. 基于 http 模块,创建 Web 服务
  5. *  2. 使用 req.url 获取请求资源路径,并读取 index.html 里字符串内容返回给请求方
  6. *  3. 其他路径,暂时返回不存在提示
  7. *  4. 运行 Web 服务,用浏览器发起请求
  8. */
  9. const fs = require('fs')
  10. const path = require('path')
  11. // 1. 基于 http 模块,创建 Web 服务
  12. const http = require('http')
  13. const server = http.createServer()
  14. server.on('request', (req, res) => {
  15.   // 2. 使用 req.url 获取请求资源路径,并读取 index.html 里字符串内容返回给请求方
  16.   if (req.url === '/index.html') {
  17.     fs.readFile(path.join(__dirname, 'dist/index.html'), (err, data) => {
  18.       res.setHeader('Content-Type', 'text/html;charset=utf-8')
  19.       res.end(data.toString())
  20.     })
  21.   } else {
  22.     // 3. 其他路径,暂时返回不存在提示
  23.     res.setHeader('Content-Type', 'text/html;charset=utf-8')
  24.     res.end('你要访问的资源路径不存在')
  25.   }
  26. })
  27. server.listen(8080, () => {
  28.   console.log('Web 服务启动了')
  29. })
复制代码
 


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

干翻全岛蛙蛙

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表