Web前端105天-day32-HTML5_CORE

news2024/11/21 0:17:15

HTML5CORE02

目录

前言

一、复习

二、拖拽

三、上传服务器

四、Canvas

五、地图

总结


前言

HTML5CORE02学习开始


一、复习

  • 跨域
    • 浏览器的同源策略导致
    • 在网页中, 通过 AJAX 发送网络请求时, 默认只能向同源的服务器请求
    • 同源: 协议 端口号 域名 三者都相同
  • 产生跨域的原因: 目前流行前后端分离 开发模式
  • 由于 静态网页服务器接口服务器 非同源, 所以产生跨域问题
  • 解决方案:
    • CORS: 最佳的解决方案
      • 在服务器利用 cors 模块解决即可
      • 原理: 接口服务器告知浏览器, 允许其他来源的访问
    • PROXY: 代理模式 -- 适合临时解决
      • 服务器无法添加cors 的场景
      • 采用 express-http-proxy模块 转发请求
    • JSONP
      • 利用 script 的 src 获取数据没有跨域限定
      • 需要 服务器 和 前端配合, 共同解决跨域问题
  • 文件上传
    • 服务器端
    • 使用 multer 模块实现
const upload = multer({
    storage: multer.diskStorage({
        desctination: 'upload', // 存放上传文件的目录
        filename(req, file, cb){
            // 根据上传的文件信息, 提供存储时 对应的文件名
        }
    })
})
  • 前端
    • Form表单模式
      • 由于功能过于单一, 使用较少
    • DOM模式
      • 通过DOM操作, 手动制作 FormData 对象
        • 验证数据大小
        • 验证数据的格式
      • 利用 AJAX 实现文件上传
        • 监听上传进度, 来实现进度条

二、拖拽

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>拖拽操作 09:15</title>

  <style>
    #box {
      background-color: #bbb;
      width: 500px;
      height: 300px;
    }
  </style>
</head>

<body>
  <!-- HTML5中 新增了拖拽操作 -->
  <!-- 默认 图片 和 超链接 均支持拖拽, 其他标签不支持 -->
  <img id="img1" src="./imgs/smallskin-1.jpg" width="100" alt="">
  <a id="a1" href="http://www.baidu.com">百度一下</a>
  <!-- draggable: 控制是否可以拖拽 -->
  <p draggable="true" id="p1">Hello P!</p>

  <div id="box"></div>

  <script>
    const a1 = document.getElementById('a1')
    a1.ondragstart = function (e) {
      e.dataTransfer.setData('text', 'a1')
    }

    const img1 = document.getElementById('img1')
    img1.ondragstart = function (e) {
      e.dataTransfer.setData('text', 'img1')
    }


    const p = document.querySelector('p')
    // 在用户开始拖拽元素时触发
    p.ondragstart = function (e) {
      console.log('p被拖拽 ondragstart', e)
      // dataTransfer: 数据传输者 -- 用于在事件中保存一些信息
      // setData: 用于设置数据
      // 参数1: 固定的值,  'text' 代表文本类型的信息
      // 参数2: 自定义的值, 此处 p1 是拖拽的元素的id
      e.dataTransfer.setData('text', 'p1')
    }
    // 处于拖拽状态时, 每隔 350毫秒, 0.35秒 触发一次
    p.ondrag = function (e) {
      // console.log('p被拖动 ondrag', e);
    }
    // 拖动结束时
    p.ondragend = function (e) {
      console.log('拖动结束 ondragend');
    }

    //
    // 盒子
    const box = document.getElementById('box')

    box.ondragenter = function () {
      console.log('拖拽元素进入盒子范围 ondragenter');
    }
    // 每隔350ms 触发一次
    box.ondragover = function (e) {
      // console.log('拖拽元素在盒子范围内 ondragover');
      // 默认事件操作: 不允许元素被放下到盒子里
      // 阻止事件的默认行为, 盒子不会排斥拖拽的元素
      e.preventDefault()
    }

    box.ondragleave = function () {
      console.log('拖拽元素离开盒子范围 ondragleave');
    }

    // 检测到有元素被放置到盒子中
    box.ondrop = function (e) {
      // 问题: 如何区分被放下的元素是什么?
      console.log('有元素被放下 ondrop:', e)

      // 读取数据传输者中 存放的信息
      var el_id = e.dataTransfer.getData('text')
      // 通过id 读取被放下的元素
      var el = document.getElementById(el_id)
      // 添加到盒子里
      box.appendChild(el)
    }
  </script>
</body>

</html>
  • 文件拖拽
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>文件拖拽 10:21</title>

  <style>
    #box {
      background-color: #aaa;
      width: 300px;
      height: 300px;
    }
  </style>
</head>

<body>
  <button>上传</button>
  <div id="box"></div>

  <script>
    const box = document.getElementById('box')

    // 阻止路过自身上方的元素的默认行为
    box.ondragover = function (e) {
      e.preventDefault()
    }

    box.ondrop = function (e) {
      e.preventDefault()

      console.log('被放下的元素', e);
      console.log(e.dataTransfer.files);

      var file = e.dataTransfer.files[0]
      this.innerHTML = file.name
    }
  </script>
</body>

</html>

三、上传服务器

  • 1.制作文件夹:upload-server
  • 2.初始化命令: npm init -y
  • 3.安装模块: npm i express uuid multer cors
  • 4.制作 app.js 文件, 完成基本服务器的启动代码, 端口3000
  • 5.制作静态文件夹 public
    • app.js 中, 指定 public 为静态托管文件夹
    • 在 public 下创建 index.html , 书写 h1 标签, 显示 欢迎 文字
    • 把 jquery.min.js 引入到 public 目录中
  • 6.在 app.js 中添加 multer 模块, 完成单文件的一系列操作
    • 指定 upload 目录保存上传文件
    • 个性化 配置上传文件的名字
    • 添加 post方式的 /upload 接口, 用于接收单文件
const express = require('express');
const cors = require('cors');
const uuid = require('uuid');
const multer = require('multer');

const app = express()
app.listen(3000, () => {
  console.log('服务器启动');
})

app.use(express.static('public'))

app.use(cors())

const upload = multer({
  storage: multer.diskStorage({
    destination: 'upload',
    filename(req, file, cb) {
      var dian_index = file.originalname.lastIndexOf('.')
      var ext = file.originalname.substr(dian_index)

      cb(null, uuid.v4() + ext)
    }
  })
})

// 单文件
app.post('/upload', upload.single('avatar'), (req, res) => {
  res.send(req.file)
})

// 多文件
// 变化1: upload.array  代表收到的文件是多个
// 变化2: req.files 代表多个文件的信息
app.post('/uploads', upload.array('avatars'), (req, res) => {
  res.send(req.files)
})
  • 单文件
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>首页</title>
  <style>
    #box {
      background-color: #aaa;
      height: 200px;
      padding: 10px;
    }
  </style>
</head>

<body>
  <h1>欢迎使用文件上传</h1>
  <!-- 不要使用live server, 会导致上传后 自动刷新 -->
  <div id="box"></div>
  <button>上传</button>

  <script src="./jquery-3.6.1.min.js"></script>
  <script>
    let files = null //用于存放拖拽的文件信息

    $('#box')
      .on('dragover', function (e) {
        e.preventDefault()
      })
      .on('drop', function (e) {
        // jQuery触发的事件参数 e  是经过封装的, 并非原生的事件参数
        // 其中的 originalEvent 存储了原生的事件参数
        e.preventDefault()
        console.log('drop', e);
        // 存放到全局的 files 属性
        files = e.originalEvent.dataTransfer.files
        console.log('files', files);

        $('#box').empty() //清空
        for (const file of files) {
          $('#box').append(`<div>${file.name}</div>`)
        }
      })

    // 单文件上传
    $('button').click(function () {
      // FormData
      var fd = new FormData()
      fd.append('avatar', files[0])

      $.ajax({
        type: 'post',
        data: fd,
        contentType: false,
        processData: false,
        url: 'http://localhost:3000/upload',
        success(res) {
          console.log(res);
        }
      })
    })
  </script>
</body>

</html>
  • 多文件
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>首页</title>
  <style>
    #box {
      background-color: #aaa;
      height: 200px;
      padding: 10px;
    }
  </style>
</head>

<body>
  <h1>欢迎使用文件上传</h1>
  <!-- 不要使用live server, 会导致上传后 自动刷新 -->
  <div id="box"></div>
  <button>上传</button>

  <script src="./jquery-3.6.1.min.js"></script>
  <script>
    let files = null //用于存放拖拽的文件信息

    $('#box')
      .on('dragover', function (e) {
        e.preventDefault()
      })
      .on('drop', function (e) {
        // jQuery触发的事件参数 e  是经过封装的, 并非原生的事件参数
        // 其中的 originalEvent 存储了原生的事件参数
        e.preventDefault()
        console.log('drop', e);
        // 存放到全局的 files 属性
        files = e.originalEvent.dataTransfer.files
        console.log('files', files);

        $('#box').empty() //清空
        for (const file of files) {
          $('#box').append(`<div>${file.name}</div>`)
        }
      })

    // 单文件上传
    $('button').click(function () {
      // FormData
      var fd = new FormData()
      // 多文件, 用变量进行数据的添加
      for (const file of files) {
        fd.append('avatars', file)
      }

      $.ajax({
        type: 'post',
        data: fd,
        contentType: false,
        processData: false,
        url: 'http://localhost:3000/uploads',
        success(res) {
          console.log(res);
        }
      })
    })
  </script>
</body>

</html>

四、Canvas

  • 入门
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>canvas 14:01</title>
  <style>
    /* 图片具有两种宽高: 1.原始宽高  2.显示宽高 */
    /* canvas上设置的 width 和 height 是图片的原本宽高 */
    /* css 上设置的是 图片显示的宽高 */
    #c1 {
      /* 显示时, 宽高与原图不同, 则会拉伸 或 压缩 */
      width: 400px;
      /* height: 800px; */
    }
  </style>
</head>

<body>
  <!-- canvas : 画布;  来自HTML5 新增的标签, 赋予了 HTML 画图能力 -->
  <!-- 可以利用 JS 代码来 实时绘制图片 -->
  <!-- 场景: 地图, 图表, 网页游戏... -->
  <!-- 实时根据数据, 绘制不规则的 样式丰富的 图形 -->

  <!-- width: 设置画布的宽度 -->
  <!-- height: 设置画布的高度 -->
  <canvas id="c1" width="400" height="400" style="background-color: gray;"></canvas>

  <script>
    // 通过规范的注释, 告诉vscode 变量c1 的类型是画布, 才能得到提示
    /** @type {HTMLCanvasElement} */
    var c1 = document.getElementById('c1')
    console.dir(c1)

    // 1.找到 画布中提供的 绘制工具
    // 使用说明: https://www.runoob.com/tags/ref-canvas.html
    var ctx = c1.getContext('2d') //绘制2d图形的工具箱
    console.log(ctx)

    ctx.strokeStyle = 'green' //笔触的颜色    
    ctx.lineWidth = 5  // 默认单位 px
    // 左上角的坐标x,y ;   宽和高
    ctx.strokeRect(50, 50, 150, 150)

    // 在 60,60  坐标,  绘制 120, 120 宽高的 填充矩形, 填充红色red
    ctx.fillStyle = 'red'
    ctx.fillRect(60, 60, 120, 120)

    // 画一条线: 把画笔移动到起始点 -- 60,60
    // 线段颜色 blue
    // 移动到 180, 180 坐标
    // 开始画线
    ctx.beginPath() // 开始绘制路径
    ctx.moveTo(60, 60) // 从60,60坐标开始
    ctx.lineTo(180, 180) // 画线到指定坐标
    ctx.strokeStyle = 'blue'  //线的颜色
    ctx.stroke() // 绘制
  </script>
</body>

</html>
  • 柱状图
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>练习 15:16</title>
</head>

<body>
  <canvas id="c1" width="800" height="300" style="background-color: #bbb;"></canvas>

  <script>
    var data = [
      { value: 146, color: 'pink' },
      { value: 72, color: 'black' },
      { value: 60, color: 'orange' },
      { value: 102, color: 'blue' },
      { value: 75, color: '#ff68b5' },
      { value: 43, color: '#fea600' },
      { value: 120, color: '#ce8540' },
    ]

    /** @type {HTMLCanvasElement} */
    var c1 = document.getElementById('c1')

    var ctx = c1.getContext('2d')

    // 坐标轴的竖线
    ctx.beginPath()
    ctx.moveTo(20, 20)
    ctx.lineTo(20, 280)
    ctx.lineTo(780, 280)
    ctx.stroke()

    // 竖着
    data.forEach((item, index) => {
      const { value, color } = item

      var h = 20
      var space = 10 //距离
      var x = 21
      var w = value
      var y = 280 - (index + 1) * (h + space)

      ctx.fillStyle = color
      ctx.fillRect(x, y, w, h)
    })

    // 横着
    // data.forEach((item, index) => {
    //   const { value, color } = item

    //   // 矩形左上角的 y
    //   var y = 280 - value
    //   var w = 50 //宽度
    //   var space = 20 //间距
    //   var h = value //高
    //   var x = (index + 1) * space + index * w + 20

    //   ctx.fillStyle = color
    //   ctx.fillRect(x, y, w, h)
    // })
  </script>
</body>

</html>
  • 文本绘制
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>绘制文本 16:16</title>
</head>

<body>
  <canvas id="c1" width="500" height="500" style="background-color: #ccc;"></canvas>

  <script>
    /** @type {HTMLCanvasElement} */
    var c1 = document.getElementById('c1')

    var ctx = c1.getContext('2d')

    // 渐变色:
    var co = ctx.createLinearGradient(0, 0, 250, 50)
    co.addColorStop(0, 'blue') // 开头的颜色
    co.addColorStop(0.5, 'purple') // 一半的颜色
    co.addColorStop(1, 'brown') // 最后的颜色

    ctx.fillStyle = co

    ctx.font = '50px 微软雅黑'
    // 参数2 和 参数3: 代表文本的左下角坐标
    ctx.fillText("填充的文本", 10, 50)

    ctx.font = '50px 微软雅黑'
    ctx.strokeText('描边文本', 10, 120)
  </script>
</body>

</html>

五、地图

  • 文档地址:高德开放平台 | 高德地图API

  •  按照教程准备进行操作
    • 登录账号以后, 在控制台创建新应用
    • 名称和类型 根据实际情况填写, 可以随便写

  •  添加一个key: 类似玩游戏时 要先新建角色

 

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>map 16:32</title>

  <style>
    #container {
      width: 500px;
      height: 500px;
    }

    .home {
      list-style: none;
      margin: 0;
      background-color: #eee;
      border-radius: 4px;
      padding: 4px;
    }
  </style>
</head>

<body>
  <!-- 地图: 百度地图, 腾讯, 谷歌, 高德... -->
  <!-- 这些厂商 开发了一些地图的API 可以使用 -->
  <!-- 高德地图开放平台: https://lbs.amap.com/ -->

  <div id="container"></div>

  <script type="text/javascript">
    window._AMapSecurityConfig = {
      securityJsCode: '1c93d9f935422a937e3e4352acd10b6a',
    }
  </script>
  <script type="text/javascript" src="https://webapi.amap.com/maps?v=2.0&key=6f7aeb74b1f6e28d7d820dbc7eb9f315"></script>

  <script>
    // 快速上手
    // 把 #container 初始化为地图
    // 参数1: 把 指定id的元素, 转换成地图
    // 参数2: 各种配置
    var map = new AMap.Map('container', {
      zoom: 11, //缩放级别
      // 坐标拾取器, 可以获取地址的经纬度
      // https://lbs.amap.com/tools/picker
      center: [116.39, 39.9], //中心点坐标
      viewMode: '3D', // 使用功能 3D 视图
      layers: [//使用多个图层
        new AMap.TileLayer.Satellite(),
        new AMap.TileLayer.RoadNet()
      ],
    });

    //实时路况图层
    var trafficLayer = new AMap.TileLayer.Traffic({
      zIndex: 10
    });
    map.add(trafficLayer);//添加图层到地图

    // 标记点
    var marker = new AMap.Marker({
      position: [116.39, 39.9]//位置
    })
    map.add(marker);//添加到地图

    // 标记点 点击弹窗
    var infoWindow = new AMap.InfoWindow({ //创建信息窗体
      isCustom: true,  //使用自定义窗体
      content: `<ul class="home">
        <li>亮亮的小屋</li>
        <li>营业时间  09:00 - 22:00</li>
        <li>联系方式: 18811718888</li>
        </ul>`, //信息窗体的内容可以是任意html片段
      offset: new AMap.Pixel(16, -45)
    });
    var onMarkerClick = function (e) {
      infoWindow.open(map, e.target.getPosition());//打开信息窗体
      //e.target就是被点击的Marker
    }
    var marker = new AMap.Marker({
      position: [116.481181, 39.989792]
    })
    map.add(marker);
    marker.on('click', onMarkerClick);//绑定click事件

    // 插件的使用:
    AMap.plugin('AMap.ToolBar', function () {//异步加载插件
      var toolbar = new AMap.ToolBar();
      map.addControl(toolbar);
    });

    AMap.plugin(['AMap.ToolBar', 'AMap.MapType', 'AMap.Scale', 'AMap.HawkEye', 'AMap.Geolocation'], function () {//异步同时加载多个插件
      var toolbar = new AMap.ToolBar();
      map.addControl(toolbar);

      var maptype = new AMap.MapType()
      map.addControl(maptype)

      var scale = new AMap.Scale()
      map.addControl(scale)

      var hawkeye = new AMap.HawkEye({ position: 'LT' })
      map.addControl(hawkeye)

      var geolocation = new AMap.Geolocation()
      map.addControl(geolocation)
    });


    //加载天气查询插件
    AMap.plugin('AMap.Weather', function () {
      //创建天气查询实例
      var weather = new AMap.Weather();

      //执行实时天气信息查询
      weather.getLive('北京市', function (err, data) {
        console.log(err, data);
      });
    });
  </script>
</body>

</html>


总结

HTML5CORE02学习结束

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/110315.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

RocketMQ疑难杂症之No route info of this topic解决方案

成因&#xff1a; 由于配置了 docker 虚拟 IP&#xff0c;导致 brocker 总是代理到 docker 的虚拟 IP 上。 原理&#xff1a; RocketMQ 的 broker 启动类 org.apache.rocketmq.broker.BrokerStartup 启动的时候会读取代码中的默认配置&#xff0c;关于 broker 的配置在 org.apa…

【关于时间序列的ML】项目 8 :使用 Facebook Prophet 模型预测股票价格

&#x1f50e;大家好&#xff0c;我是Sonhhxg_柒&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流&#x1f50e; &#x1f4dd;个人主页&#xff0d;Sonhhxg_柒的博客_CSDN博客 &#x1f4c3; &#x1f381;欢迎各位→点赞…

30.深度学习模型压缩方法-4

30.1 低秩分解 基于低秩分解的深度神经网络压缩与加速的核心思想是利用矩阵或张量分解技术估计并分解深度模型中的原始卷积核 卷积计算是整个卷积神经网络中计算复杂 度 最 高 的 计 算 操 作,通 过 分 解4D 卷积核张量,可以有效地减少模型内部的冗余性此外对于2D的全 连…

Hive+Spark离线数仓工业项目实战--项目介绍及环境构建(1)

项目简介 通过大数据技术架构&#xff0c;解决工业物联网制造行业的数据存储和分析、可视化、个性化推荐问题。一站制造项目主要基于Hive数仓分层来存储各个业务指标数据&#xff0c;基于sparkSQL做数据分析。核心业务涉及运营商、呼叫中心、工单、油站、仓储物料。 推荐教程…

DSP_TMS320F28377D_eCAP学习笔记

博主学习eCAP的使用主要是用于处理霍尔传感器&#xff0c;计算电机的电角度以及角速度。首先还是看了点哔哩哔哩的学习视频。 eCAP介绍 脉冲量的输入是在数字控制系统中最常见的一类输入量&#xff0c;控制器专门设置了脉冲捕获模块 (eCAP)来处理脉冲量&#xff0c;通过脉冲捕…

路由器的工作原理(计算机网络-网络层)

目录 路由器的构成 转发和路由选择的区别 典型的路由器结构 交换结构 输出端口 路由器与交换机的比较 两种基于存储转发的分组交换设备的比较 交换机和路由器各有的应用场合 三层交换机 三层交换机的应用 路由器的构成 路由器的任务 路由器是一种具有多个输入端口和多…

MT8385 Android AB分区系统升级(命令模式)

AB系统分区升级使用的是update_engine,RecoverySystem 只适用于单分区的系统升级 1.解压开update.zip 可以查看到palyload的属性 2.使用ADB命令update_engine_client即可对AB分区进行升级 使用adb shell 命令进行升级 update_engine_client --payload xxx --update --header…

【TypeScript】TS类型声明(二)

&#x1f431;个人主页&#xff1a;不叫猫先生 &#x1f64b;‍♂️作者简介&#xff1a;前端领域新星创作者、华为云享专家、阿里云专家博主&#xff0c;专注于前端各领域技术&#xff0c;共同学习共同进步&#xff0c;一起加油呀&#xff01; &#x1f4ab;系列专栏&#xff…

k8s HPA升级 KEDA 基于prometheus的数据指标进行弹性伸缩

说明&#xff1a;KEDA有啥用&#xff0c;相对HPA有啥优势。HPA针对于cpu,内存来进行弹性伸缩&#xff0c;有点不太精确。KEDA可以接入prometheus&#xff0c;根据prometheus的数据指标进行弹性伸缩&#xff0c;相比更加的精准实用。 安装k8s环境部署prometheus 创建ns&#xf…

【软件测试】那些35岁以上的测试人哪去了?

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 先根据大体年龄阶段…

B+树详解,一次就懂

⭐注意&#xff1a;不会直接讲 B树的结构&#xff0c;会从最简单的二叉树开始讲起来。如果认真看完&#xff0c;我想你对树类型的数据结构的理解又上了一个新的台阶。 ⭐如果有误&#xff0c;请大家指出。下文均是在B站学习的过程中&#xff0c;总结的笔记和心得体会 索引结构 …

四、网络层(五)IP组播

目录 5.1 组播的概念 5.2 IP组播的地址 5.3 因特网组管理协议&#xff08;IGMP&#xff09; 5.4 组播路由算法 5.1 组播的概念 为了更好地支持像视频会议这类一对多的通信&#xff0c;需要源主机一次发送的单个分组&#xff0c;能抵达用一个组地址标识的若干台目的主…

【老保姆教程】:Tesseract-OCR图片文字识别

文章目录&#x1f31f;介绍一波&#x1f31f;小安装&#x1f31f;配置环境变量⭐️tesseract-ocr配置⭐️tessdata语言配置⭐️检测环境变量是否安装成功&#x1f31f;语言包的配置使用&#x1f31f;CMD命令框中进行图片识别操作⭐️举例一&#xff1a;识别数字⭐️举例二&…

@PostConstruct(重点,初始化加载)和@PreDestroy 注解

PostConstruct和PreDestroy 注解 PostConstruct和PreDestroy都是属于Bean生命周期的一部分&#xff1b; PostConstruct&#xff1a;在bean创建完成并且属性赋值完成之后来执行初始化方法&#xff0c;常用于:项目启动完成后的初始化操作&#xff0c;比如不经常变的Redis缓存Pr…

二、LVS的安装部署

LVS的安装部署LVS的安装部署一、LVS的安装1、yum安装2、源码包安装二、ipvsadm命令详解LVS 相关软件ipvsadm 命令ipvsadm 工具用法&#xff1a;防火墙标记LVS 持久连接三、部署LVS NAT1、LVS NAT模式注意事项2、实验环境3、部署RS1和RS2的nginx4、将RS1和RS2的网关配置为DR的内…

maven私服

分模块开发时&#xff0c;被引用的模块不可能拷来拷去&#xff0c;应该放在单位内部的某一个服务器上&#xff0c;这就是私服。这里使用nexus作为私服软件。 Nexus ● Nexus是Sonatype公司的一款maven私服产品 ●下载地址 Nexus安装、启动与配置 ● 解压即安装 ● 修改基…

我国登山鞋行业参与者越发广泛带来广阔潜在需求 女性市场值得期待

登山鞋属于户外运动鞋&#xff0c;是专门为爬山和旅行而设计制造的鞋子&#xff0c;具有防水性、防滑性、足部保护功能、耐用性等功能&#xff0c;其中防水性是现代登山鞋的首要功能。 资料来源&#xff1a;中国登山鞋行业发展趋势研究与未来投资分析报告&#xff08;2022-2029…

StarRocks Join Reorder 源码解析

导读&#xff1a;欢迎来到 StarRocks 源码解析系列文章&#xff0c;我们将为你全方位揭晓 StarRocks 背后的技术原理和实践细节&#xff0c;助你逐步了解这款明星开源数据库产品。 本期 StarRocks 技术内幕将介绍 Join Reorder 算法如何找到最优解的原理。 背景介绍 多表 Join…

vue之watchEffect

在Options API中&#xff0c;我们可以通过watch选项来侦听data或者props的数据变化&#xff0c;当数据变化时执行某一些操作。 在Composition API中&#xff0c;我们可以使用watchEffect和watch来完成响应式数据的侦听。 watchEffect用于自动收集响应式数据的依赖&#xff0c;需…

Jmeter实现websocket协议接口测试

一&#xff0e;为了方便使用&#xff0c;首先将jmeter设置成中文&#xff0c;有两种方法&#xff1a; 1.在Jmeter界面进行设置&#xff0c;Options ->Choose Language ->Chinese(Simplified)&#xff0c;这种方法在关闭jmeter重启后又会恢复成默认的英文&#xff0c;如果…