【Flutter_Web】Flutter编译Web第二篇(webview篇):flutter_inappwebview如何改造方法,变成web之后数据如何交互
前言
欢迎来到第二篇文章,这也是第二个难题,就是原有的移动端本身一些页面H5的形式去呈现(webview)
,例如某些需要动态更换内容的页面,某些活动页面、支付页面,不仅仅做页面呈现,还包括一些数据交互
,那么在项目初期,我们尝试使用过了官方提供的webview,但是功能比较有限,因此我们选择了flutter_inappwebview
这个插件
- 官网webview
https://pub.dev/packages/webview_flutter
- flutter_inappwebview
https://pub.dev/packages/flutter_inappwebview
本文以flutter_inappwebview
为案例,将陈述我将Flutter编译成web之后,如果去处理flutter_inappwebview
的。
原理
我想在讲之前,先讲讲什么是webview?
实际上对我来说,webview应该相对于原生端而已(ios、android),是由原生提供的底层网页环境容器
,去呈现网页内容,那么不同端,他们提供的环境当然是不一样的,因为网页内核不一样,那么也会造成很多的差异,所以为了抹平这些差异,才会提供第三方插件,封装公共的api供顶层调用,底层由各个平台去进行实现
。
例如我之前的文章提到过的数据交互,本质上就是在当前环境去注入某些方法、某些类去给网页容器提供交互的能力。
那么对于flutter_inappwebview
而言,它给每一个网页容器提供了一个控制器,这个控制器有一个addJavaScriptHandler
方法,可以连接到网页容器,实现监听和传输数据,同时给网页容器放了一个公共的类window.flutter_inappwebview
类提供网页传输数据到客户端的能力。
那么我说webview应该相对于原生端而已,因为Flutter在编译成web之后,本质上就是web,那么之前的网页就不能叫webview,应该叫iframe。
那么我们的问题,实际上就是web和iframe的数据交互问题。
实现
那么,如果你明白本质是web和iframe的数据交互问题,你就明白为什么addJavaScriptHandler
方法在web平台没有实现的原因,因为压根就不需要注入,他们本身就已经在一个环境下面了。
由于浏览器有同源策略,所以我们还是使用postMessgae的方法,但有一些地方需要注意。
实际上flutter_inappwebview有对web端的某些api进行封装,编译成web,那么之前的iframe的配置在flutter_inappwebview的options里面也会存在。
InAppWebViewSettings getInAppWebViewGroupOptions() {return InAppWebViewSettings()..useShouldInterceptAjaxRequest = false..useShouldInterceptFetchRequest = false..supportZoom = true..clearCache = true..iframeName = 'my_ifram' //设定ifame的名称,这个就是给web环境使用的..mediaPlaybackRequiresUserGesture = true..transparentBackground = true..allowsInlineMediaPlayback = false;}
同样验证的方式,你可以编译成web之后,之前的webview,在浏览器标签上也可以得知上iframe。
我们可以看编译之后的产物:
- 首先id固定为flutter_inappwebview-0
- 有csp,防止内部js脚本攻击(部分浏览器不可用)
- 有sandbox模式,也就是沙箱模式,可以进行配置,对iframe做一些限制
- src转成hash链接
- 默认为全屏模式
和iframe通信的方式网上有很多方法,我这里不过多赘述。
父页面发送:
//获取子iframe,通过name属性或者直接拿第一个iframeweb.HTMLIFrameElement childIframe = web.document.getElementById("flutter_inappwebview-0") as web.HTMLIFrameElement; //这里最好根据前面设定的名称去找Map data = {'user': {'token': 1111}};JSString msg = jsonEncode(data).toJS;//给子ifram传递数据// childIframe.contentWindow?.postMessage(msg, '*'.toJS);//这种方式是不行的childIframe.contentWindowCrossOrigin?.postMessage(msg, '*'.toJS);
父页面接收:
//监听子组件传递过来的消息web.window.addEventListener('message', callback.toJS);void callback(web.MessageEvent e) {print("收到js交互=====${e}");}
iframe发送:
window.top.postMessage('hello', '*')
iframe接收:
window.addEventListener('message', (event) => {console.log("ssss", event.data)})
难点
条件编译
尽管Flutter支持web端
但当编译成web端时,此时如果使用到了io库(Platform相关)都会在编译时报错。
当编译成原生端,使用web端相关的库(web、js库)同样也会在编译时报错。
那么你就需要进行文件的替换工作,让Flutter在编译时,根据不同的端去引入不同的文件。
比如这一段代码:
web.window.addEventListener('message', callback.toJS);void callback(web.Event e) {print("收到js交互=====${e.data.dartify()}");}
这里我们需要一定要使用到web库相关的内容,才有window环境以及调用addEventListener,但是你在原生端,这段代码会让你在编译时就报错了。
因此你需要去做文件替换。
自己创建两个文件:
import './vm/ai_web_js.dart' if (kIsWeb) 'dart:js_interop';
import './vm/ai_web_window.dart' if (kIsWeb) 'package:web/web.dart' as web;
在原生端使用的是我们自己写的文件,实现的是空方法。
在web端使用对应的库文件
链接为hash链接加载空白的问题
当链接为hash链接时,iframe会将src从链接转换成另外的格式文件data:text/html
js有提供一个内置的api为encodeURIComponent
比如有一个html为:
<div id="myDiv"><h1>Hello, World!</h1><p>This is a sample HTML code.</p>
</div>
通过api编码之后变成了类似这样:
"%3Cdiv%20class%3D%22s-skin-container%20s-isindex-wrap%20skin-gray-event%22%3E%3C%2Fdiv%3E%3Cdiv%20id%3D%22head%22%20class%3D%22%22%3E%3Cdiv%20id%3D%22s_top_wrap%22%20class%3D%22s-top-wrap%20s-isindex-wrap%20%22%20style%3D%22left%3A%200px%3B%22%3E%3Cdiv%20class%3D%22s-top-nav%22%3E%3C%2Fdiv%3E%3Cdiv%20class%3D%22s-center-box%22%3E%3C%2Fdiv%3E%3C%2Fdiv%3E%3Cdiv%20id%3D%22s-top-left%22%20class%3D%22s-top-left-new%20s-isindex-wrap%22%3E%3Cstyle%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20.aitab-image-long%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20width%3A%2049px%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20height%3A%2014px%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20margin-bottom%3A%20-2px%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20.aitab-image-short%20%7B%0A%20%20%20%20%20%20%20%20%20%
然后再加上前缀data:text/html,
这种特殊格式标识变成URL:
const dataURL = "data:text/html," + encodedHTML;
放入iframe的src中去进行处理。
但是当我们的链接是hash链接,我们打包成web项目可以选择hash路由或者history路由,hash路由是通过监听hash值的变化去响应不同的js数据在同一个html去做不同的渲染
。
那么这个时候,就要求你的html中的js必须能够正常请求响应,才能触发监听去做数据的呈现。
测试发现,当链接为hash链接时,能正常展示html,但是内部需要的js已经不做网络请求了,因为根本就不是加载链接,而是加载一个普通的文本
<!DOCTYPE html>
<html lang=zh-CN><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><title>aiyjcp</title><script>var coverSupport = 'CSS'in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') || CSS.supports('top: constant(a)'))document.write('<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' + (coverSupport ? ', viewport-fit=cover' : '') + '" />')</script><link rel=stylesheet href=./static/index.2da1efab.css></head><body><noscript><strong>Please enable JavaScript to continue.</strong></noscript><div id=app></div><script src=./static/js/chunk-vendors.bc6b93b6.js></script><script src=./static/js/index.d07f5f7d.js></script></body>
</html>
那么,至此我们就发现了问题了:
原因在于flutter_inappwebview会对url获取html文本,进行转码变成特殊的url格式(data:text/html格式),但是加载出html之后,内部需要的js和css都不进行网络请求获取,导致无法监听到hash值的变化以及所需要的资源,导致可能出现页面空白(如果你使用hash路由),或者样式丢失(如果你使用history路由)
那么就有三种解决方案:
- 第一种,不要让插件对URL进行转码
- 第二种,研究如何让转码还原之后的html再次进行网络请求加载出需要的JS和CSS文件
- 第三种,再嵌套一层iframe,插件对第一层进行转码还原之后,内部还是一个iframe,这个时候内部的iframe就不会对src进行再次转码了,但是这种情况,数据通信又需要做改变,由父子关系,变成父到子再到孙子关系
问题出在配置上面:
之前在原生端对url做了处理:
key: webViewKey,initialUrlRequest: URLRequest(url: url.startsWith("http")? WebUri.uri(Uri.parse(url)): WebUri.uri(Uri.file(url)),
但是在web环境并且使用了非安全模式
,这种方式会对url进行转码,因此你如果需要打开iframe,请关闭安全模式,网络跨域使用本地代理的方式
"name": "dev_web","request": "launch","type": "dart","args": ["--target","lib/ai_main_dev.dart",// "--web-browser-flag",// "--disable-web-security","--web-renderer","html"]
跨域问题
可以使用这个浏览器插件:
https://chromewebstore.google.com/detail/cors-unblock/lfhmikememgdcahcdlaciloancbhjino
数据传递和交互问题
Js是弱语言类型,Dart是强语言,两种不同类型的数据互相转换在某种数据格式上是不被支持的,但是String、num、boolean这种基础数据类型是被允许的,因此我们需要尽量保持输入和输出都是字符串类型的,再到不同场景去解析即可。
例如iframe端传送过来的数据,我需要在dart层提前声明,然后进行转换,变成dart端的数据,在传输回去的时候,同样变成js端的数据传输回去,类型都是string,都能被支持。
尽管这种方式解决了编译和运行的问题,但是却失去了相应的代码提示,如果你有更好的方法,欢迎在下方提出,下一篇会解决Dio以及请求相关的问题
相关文章:
【Flutter_Web】Flutter编译Web第二篇(webview篇):flutter_inappwebview如何改造方法,变成web之后数据如何交互
前言 欢迎来到第二篇文章,这也是第二个难题,就是原有的移动端本身一些页面H5的形式去呈现(webview),例如某些需要动态更换内容的页面,某些活动页面、支付页面,不仅仅做页面呈现,还包…...
【游戏中orika完成一个Entity的复制及其Entity异步落地的实现】 1.ctrl+shift+a是飞书下的截图 2.落地实现
一、orika工具使用 1)工具类 package com.xinyue.game.utils;import ma.glasnost.orika.MapperFactory; import ma.glasnost.orika.impl.DefaultMapperFactory;/*** author 王广帅* since 2022/2/8 22:37*/ public class XyBeanCopyUtil {private static MapperFactory mappe…...
全局JDK环境和ES自带的JDK混用导致的ES集群创建失败
es配置安全集群es使用的自带的jdk环境,如果服务器全局在有jdk的配置。会导致秘钥解析出问题。各种问题异常密钥解析异常。 错误日志1: [2024-12-20T17:10:44,700][WARN ][o.e.c.c.ClusterFormationFailureHelper] [es-node1] master not discovered yet…...
vmime.net_4.dll详解:它是什么,有何用途?
在.NET开发环境中,DLL(Dynamic Link Library,动态链接库)文件扮演着至关重要的角色。它们封装了代码和资源,使得多个应用程序可以共享这些功能,从而提高开发效率和代码复用性。本文将详细介绍vmime.net_4.d…...
K8s 节点 NotReady 后 Pod的变化
NotReady 后 Pod的变化 当Kubernetes(K8s)节点进入NotReady状态时,该节点将无法接收新的Pod调度,这可能会影响服务的可用性。以下是节点变为NotReady后,其上Pod状态可能发生的一些情况和细节: Pod状态变为…...
使用 esrally race 测试 Elasticsearch 性能:实践指南
在 Elasticsearch 性能优化和容量规划中,使用 esrally 进行基准测试是官方推荐的方式。通过 esrally race 命令,您可以针对不同的数据集与挑战类型,对 Elasticsearch 集群进行精确的性能评估。本文将简要介绍常用的数据集与挑战类型ÿ…...
对象、函数、原型之间的关系
在 JavaScript 中,对象、函数 和 原型 是三者紧密联系的核心概念。它们共同构成了 JavaScript 中面向对象编程的基石,并通过原型链实现了继承与代码复用。本文将从对象、函数、原型的基础概念到它们之间的关系进行详细的讲解,帮助你理解 Java…...
Showrunner AI技术浅析(二):大型语言模型
1. GPT-3模型架构详解 GPT-3是基于Transformer架构的预训练语言模型,由OpenAI开发。其核心思想是通过自注意力机制(Self-Attention)处理输入序列,并生成自然语言文本。 1.1 Transformer架构基础 Transformer架构由Vaswani等人在…...
Web安全攻防入门教程——hvv行动详解
Web安全攻防入门教程 Web安全攻防是指在Web应用程序的开发、部署和运行过程中,保护Web应用免受攻击和恶意行为的技术与策略。这个领域不仅涉及防御措施的实现,还包括通过渗透测试、漏洞挖掘和模拟攻击来识别潜在的安全问题。 本教程将带你入门Web安全攻防…...
买卖股票的最佳时机 - 合集
************* C 买卖股票问题合集 ************* Since I have finished some stocks problems. I wanna make a list of the stocks to figure out the similarities. Here is the storks topucs list, from easy to hard: 121. 买卖股票的最佳时机 - 力扣(L…...
gitlab window如何设置ssh
在GitLab中设置SSH需要以下步骤: 在GitLab账户中,导航到“用户设置”下的“SSH密钥”部分。 生成SSH密钥对(如果你还没有的话)。在Windows上,你可以使用ssh-keygen命令来生成密钥。 在命令提示符或PowerShell中运行以…...
go配置文件
https://github.com/spf13/viper viper golang中常用的配置文件工具为viper库,是一个第三方库。viper功能: 解析JSON、TOML、YAML、HCL等格式的配置文件。监听配置文件的变化(WatchConfig),不需要重启程序就可以读到最新的值。...
深度学习之超分辨率算法——SRGAN
更新版本 实现了生成对抗网络在超分辨率上的使用 更新了损失函数,增加先验函数 SRresnet实现 import torch import torchvision from torch import nnclass ConvBlock(nn.Module):def __init__(self, kernel_size3, stride1, n_inchannels64):super(ConvBlock…...
GIT命令使用手册(详细实用版)
一、git常用操作参考 第一次提交完整步骤: 1.git init; 2.git add . 3.git commit -m "初始化" 4.git remote add origin https://github.com/githubusername/demo.git 5.git pull origin master 6.git push -u origin master(使用-u选项可以将…...
数据分析实战—IMDB电影数据分析
1.实战内容 1.加载数据到movies_df,输出前5行,输出movies_df.info(),movies_df.describe() # (1)加载数据集,输出前5行 #导入库 import pandas as pd import numpy as np import matplotlib import matplotlib.pyplo…...
【SQL/MySQL 如何使用三种触发器】SQL语句实例演示
触发器介绍 – 触发器是与表有关的数据库对象,指在insert/update/delete之前(BEFORE)或之后(AFTER),触发并执行触发器中定义的SQL语句集合。 – 使用别名OLD和NEW来引用触发器中发生变化的记录内容,这与其他的数据库是相似的。现在触发器还只…...
社区团购管理系统(源码+数据库)
355.基于SpringBoot的社区团购管理系统,系统包含两种角色:管理员、用户,系统分为前台和后台两大模块,主要功能如下 二、项目技术 编程语言:Java 数据库:MySQL 项目管理工具:Maven 前端技术:Vue …...
时钟分频模块
实现时钟的二分频,四分频 1.时钟分频模块: module clk_div(input clk, //50Mhzinput rst_n,input [15:0] lcd_id,output reg lcd_pclk);reg clk_25m; reg clk_12_5m; reg …...
linux ipmitool配置机器的BMC(服务器管理后台)
前置:mgnt口和网卡1连接入内网,并分配静态ip 1. 安装 ipmitool Debian/Ubuntu: sudo apt-get update sudo apt-get install ipmitool CentOS/RHEL: sudo yum install ipmitool2. 配置 BMC 的 IP 地址 #打印当前ipmi 地址配置信息。 ipmitool lan p…...
【Springboot知识】Redis基础-springboot集成redis相关配置
文章目录 1. 添加依赖2. 配置Redis连接3. 配置RedisTemplate(可选)4. 使用RedisTemplate或StringRedisTemplate5. 测试和验证 集群配置在application.properties中配置在application.yml中配置 主从配置1. 配置Redis服务器使用配置文件使用命令行 2. 配置…...
【数据结构】八大排序
目录 一、直接插入排序 二、希尔排序 三、选择排序 四、堆排序 五、冒泡排序 六、快速排序 七、归并排序 八、计数排序 稳定性结论 稳定性:排序后相同元素之间的相对顺序是否保持不变。 一、直接插入排序 基本思想:通过构建有序序列ÿ…...
mmdetection:图片推理以及将预测标签转换为YOLO格式标签
本文记录了使用 mmdetection 进行图片推理,并将推理结果坐标格式转换为yolo格式保存在txt中的代码。 文章目录 一、图片推理二、批量处理 一、图片推理 一个图片推理的demo。 import os import mmcv from mmdet.apis import init_detector, inference_detector fr…...
CV-OCR经典论文解读|An Empirical Study of Scaling Law for OCR/OCR 缩放定律的实证研究
论文标题 An Empirical Study of Scaling Law for OCR OCR 缩放定律的实证研究 论文链接: An Empirical Study of Scaling Law for OCR论文下载 论文作者 Miao Rang, Zhenni Bi, Chuanjian Liu, Yunhe Wang, Kai Han 内容简介 本论文在光学字符识别…...
从混沌到秩序:Python的依赖管理工具分析
Python 的依赖管理工具一直没有标准化,原因主要包括: 历史发展的随意性:Python发展早期对于依赖管理的重视程度不足,缺乏从一开始就进行统一规划和设计的意识 社区的分散性:Python社区庞大且分散,众多开发…...
【系统】Windows11更新解决办法,一键暂停
最近的windows更新整的我是措不及防,干啥都要关注一下更新的问题,有的时候还关不掉,我的强迫症就来了,非得关了你不可! 经过了九九八十一难的研究之后,终于找到了一个算是比较靠谱的暂停更新的方法&#x…...
小红书关键词搜索采集 | AI改写 | 无水印下载 | 多维表格 | 采集同步飞书
小红书关键词搜索采集 | AI改写 | 无水印下载 | 多维表格 | 采集同步飞书 一、下载影刀: https://www.winrobot360.com/share/activity?inviteUserUuid595634970300317698 二、加入应用市场 https://www.yingdao.com/share/accede/?inviteKeyb2d3f22a-fd6c-4a…...
【原生js案例】前端封装ajax请求及node连接 MySQL获取真实数据
上篇文章,我们封装了ajax方法来请求后端数据,这篇文章将介绍如何使用 Node.js 来连接 MySQL,并对数据库进行操作。 实现效果 代码实现 后端接口处理 const express require("express"); const connection require("../da…...
Ubuntu将深度学习环境配置移植到新电脑
这里默认新电脑已经安装好了conda、CUDA这些,可以直接创建新的虚拟环境。 参考链接: https://blog.csdn.net/Chujun123528/article/details/143788565https://blog.csdn.net/qq_41779275/article/details/122868946https://blog.csdn.net/YajunLin/art…...
vue基础作业实验十
vue基础作业实验十 实验要求案例要点:代码以及思考style部分Vue.js 部分Vue 实例部分 这段代码是一个基于 Vue.js 的静态页面,功能包括商品品牌的添加、删除和搜索。 实验要求 一、实验的基本内容 (1)Vue模板语法。 (…...
冒泡排序(JAVA)
package com.guangyunl.f_array;import java.util.Random; import java.util.Scanner;// 数组的冒泡排序 // 冒泡排序法是采用数组中相邻元素进行比较换位 public class Demo02Bubble {public static void main(String[] args) {Demo02Bubble demo02Bubble new Demo02Bubble()…...
如何测量分辨率
一、什么是分辨率? 分辨率指的是分清物体细节的能力。分辨率是一个成像系统还原空间频率的能力。一些人只是简单的用分辨率去描述极限分辨率,但是相机在在不同的对比度的情况下还原低,中和高频率的能力,也可以显示全面综合的信息。…...
【Mysql索引优化】索引优化的最佳实现
文章目录 【Mysql优化】索引优化的最佳实现1. 全值匹配:索引的最佳使用方式2. 最左前缀法则3. 尽量使用覆盖索引:优化查询性能。减少 select \* 语句4. 范围查询优化5. 不在索引列上做任何操作(计算、函数、(自动or手动࿰…...
centos使用mkisofs构建无人值守镜像(附官方学习文档)
安装mkisofs yum install -y mkisofs 挂载镜像并确认 并拷贝文件(/mnt 为我们的工作目录) 1.3 准备自动应答文件(保存为 ins.ks) 修改系统引导 实际上就是添加inst.ks 这个引导参数 传递应答文件 传统模式引导 UEFI模式引导 打包镜像 通用选项 -v:启用详细模式&a…...
Python获取当前系统中可用的串口设备
import serial.tools.list_portsdef checkDevice(self):port_data []for port in serial.tools.list_ports.comports():port_data.append(port.description)if port_data:for devInfo in port_data:self.toolLogPrinting(可用设备 devInfo)RET Trueelse:self.toolLogPrinti…...
基于蓝牙通信的手机遥控智能灯(论文+源码)
1.系统设计 灯具作为人们日常生活的照明工具为人们生活提供光亮,本次基于蓝牙通信的手机遥控智能灯设计功能如下: (1)用户可以通过蓝牙通信模块的作用下,在手机端遥控切换智能灯不同的工作模式; &#x…...
【Prometheus 】【实战篇(五)】深入解析 Prometheus 监控指标类型:Counter、Gauge、Histogram 和 Summary
Prometheus 提供了四种核心的指标类型,分别是 Counter(计数器)、Gauge(仪表)、Histogram(直方图)和 Summary(摘要)。这些指标类型在客户端库中有具体的使用说明ÿ…...
进程间通信方式---消息队列(System V IPC)
进程间通信方式—消息队列(System V IPC) 文章目录 进程间通信方式---消息队列(System V IPC)消息队列1.消息队列进程间通信原理2.msgget 系统调用3.msgsnd 系统调用4.msgrcv 系统调用5.msgctl 系统调用6.函数使用案例7.实现生产者…...
【笔记】深度学习模型评估指标
推荐链接: (0)多分类器的评价指标 (1)泛化误差的评价方法:【机器学习】模型评估与选择(留出法、交叉验证法、查全率、查准率、偏差、方差) (2)机器学习&…...
Python语法之列表(包含检测练习)
看完后有没有学会呢?主页有一个列表知识小检测^V^ 关注我更新更多初学实例 主页还有字典的,这个系列会持续更新 列表 列表中的查找数据(index,count,len) 一 列表的格式 【数据1,数据2, 】 index():返回指定数据…...
气象与旅游之间的关系,如果借助高精度预测提高旅游的质量
气象与旅游之间存在密切的关系,天气条件直接影响旅游者的出行决策、旅游体验和安全保障。通过高精度气象预测技术,可以有效提升旅游质量,为游客和旅游行业带来显著的优势。 1. 提高游客出行决策效率 个性化天气服务:基于高精度气象预测,旅游平台可以提供个性化的天气预报服…...
JVM(Java虚拟机)分区详情
JVM(Java虚拟机)运行时数据区是Java虚拟机的内存管理模型,它包括了多个关键的内存区域,这些区域各自承担着不同的职责,共同支持着Java程序的运行。以下是JVM运行时数据区的详细介绍: 一、整体概述 JVM运行时数据区按照线程占用的情况可以分为两类:线程共享和线程独享。…...
计算机组成原理的学习笔记(2)--数据表示与运算·其二 逻辑门和加减乘
学习笔记 前言 本文主要是对于b站尚硅谷的计算机组成原理的学习笔记,仅用于学习交流。 1. 逻辑门 逻辑门是数字电路中用于执行基本逻辑运算的组件。每种逻辑门都有独特的功能和特性: 与门(AND Gate): 符号࿱…...
数据科学与SQL:如何利用本福特法则识别财务数据造假?
目录 0 本福特法则介绍 1 数据准备 2 问题分析 步骤1:提取首位数: 步骤2:计算首位数字的实际频率分布 <...
Mapbox-GL 的源码解读的一般步骤
Mapbox-GL 是一个非常优秀的二三维地理引擎,随着智能驾驶时代的到来,应用也会越来越广泛,关于mapbox-gl和其他地理引擎的详细对比(比如CesiumJS),后续有时间会加更。地理首先理解 Mapbox-GL 的源码是一项复…...
常见网络命令
个人主页:C忠实粉丝 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C忠实粉丝 原创 常见网络命令 收录于专栏【计算机网络】 本专栏旨在分享学习计算机网络的一点学习笔记,欢迎大家在评论区交流讨论💌 目录 Ping 命令 …...
Ubuntu上如何部署Nginx?
环境: Unbuntu 22.04 问题描述: Ubuntu上如何部署Nginx? 解决方案: 在Ubuntu上部署Nginx是一个相对简单的过程,以下是详细的步骤指南。我们将涵盖安装Nginx、启动服务、配置防火墙以及验证安装是否成功。 1. 更新…...
微店商品详情API:获取商品信息的高效途径
引言 在电商领域,获取商品详情是开发者和商家进行数据分析、精准营销和店铺管理的重要一环。微店作为知名的电商平台,提供了丰富的API接口供开发者使用,其中商品详情API接口尤为关键。本文将详细介绍如何使用微店API接口获取商品详情&#x…...
编程语言注释的方式
Python 单行注释 # 这是一个单行注释多行注释(本质上是跨行字符串) 这是一个多行注释的示例。它可以跨越多行。 """这是一个多行注释的示例。它可以跨越多行。 """ C 单行注释 // 这是一个单行注释 多行注释 /*这是…...
抓住节假日的机会调整ASO优化策略
节日季和全年的特殊活动为提高应用程序的知名度和下载量提供了独特的机会。忽略节假日意味着错过这些有限的扩大用户群的机会。相反,调整您的应用商店优化 (ASO) 策略以适应这些高流量时段至关重要。以下是如何在假期期间最大限度地提高应用程序的性能。 一、为什么…...
AOI外观缺陷检测机
主要功能: 快速检测产品装配缺陷,包括螺丝、元器件、端子排线、二维码、一维条码、识别读码、产品外观 Logo缺陷以及产品标签、字符缺陷检测等产品的缺陷检测。 设备优势:1.采用轻型可移动支架,可以快速对接产线工艺工序&am…...