Learning
学习任何技术谨记:理论 + 实战
实用网站
项目优化
项目缺少对客户权限的管理
高级所需技能(有哪些?)
新版本可用,是否更新新版本
接口请求失败,重连
大屏适配问题,解决方案 采用 vw
目标
- 掰手指(这坏毛病克服)
- 记单词
- 做事犹豫:本质?
大屏适配问题
- 采用缩放比例,解决大屏适配问题;屏幕比例跟设计稿不一样,会出现四周留白问题,可以通过背景来撑满
- vw, vh 适配
import dayjs from "dayjs";
import "dayjs/locale/zh-cn";
import localeData from "dayjs/plugin/localeData";
import updateLocale from "dayjs/plugin/updateLocale";
dayjs.extend(localeData);
dayjs.extend(updateLocale);
dayjs.locale("zh-cn");
dayjs.updateLocale("zh-cn", { weekStart: 1 }); // 周一作为一周的开始
// 直接这样设置周一作为一周的开始,不成功
// dayjs.locale("zh-cn", { weekStart: 1 });
iframe
规划好每天的生活
我是谁?是什么让我一直困扰?
把装机的医院都整合到一个版本中
git 分支修复和 tag
低代码插件
- vform666
- vform
- form-making
- form-create
- AI 低代码平台
- lowcode-engine(基于 react)
- tiny-engine
- form-create
- jeecg
- 流程图:logic-flow
- 卓源软件/JeeSite Vue3
前端课程学习网站
Medium 和 Dev.to 概述:这些平台上有许多关于前端架构的文章和教程,可以提供丰富的学习资源。 内容:包括架构设计案例、性能优化技巧、工具链集成经验分享等(Medium)
前端项目架构与设计模式
前端项目
- 项目架构设计
云真机测试网站
github 打开速度慢
去http://www.ip33.com/dns.html网站,输入github.com,查询,复制 Dyn DNS 的响应 ip 地址,然后在C:\Windows\System32\drivers\etc\hosts文件中添加一条记录:xx.xx.xx.xx github.com
科学上网
本地部署 AI 模型
项目换肤
访问阿玛逊 S3 存储桶
import { S3Client, GetObjectCommand } from "@aws-sdk/client-s3";
const s3Client = new S3Client({
region: "region",
endpoint: "https://region.xxxxx.com",
forcePathStyle: true,
credentials: {
accessKeyId: "accessKeyId",
secretAccessKey: "secretAccessKey",
},
});
export const getObject = async (bucket, key) => {
const params = {
Bucket: "Bucket",
Key: "xx/xxxx.png",
};
try {
const data = await s3Client.send(new GetObjectCommand(params));
// 处理数据
return data.Body;
} catch (err) {
console.error("Error", err);
}
};
dicom 图像处理(图像查看器)
科学上网
前端简历
前端静态资源 cdn
前端项目架构框架
- 微服务架构
- Monorepo 架构
AI
代码AI
- Cursor
- Claude Code
- 华为:码道(CodeArts)
图片压缩
文件预览插件
防止服务器被所有ip访问
- 限制IP访问
- 移除8080端口的公开访问
firewall-cmd --permanent --remove-port=8080/tcp
- 添加富规则,只允许特定IP
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.100" port port="8080" protocol="tcp" accept'
- 重新加载配置
firewall-cmd --reload
- 查看规则
firewall-cmd --list-all
- 限制SSH只允许特定IP
ufw allow from 信任IP to any port 22
ufw allow from x.x.x.x to any port 22
- 关闭不必要的端口
netstat -tlnp # 查看开放端口
关闭不需要的服务
启用连接速率限制
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 4 -j DROP
ASCII 字符
ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)是计算机科学史上最早、最基础且影响最为深远的字符编码标准之一,诞生于1963年,1967年定型为ANSI X3.4标准,后被国际标准化组织(ISO)定为国际标准(ISO 646)
ASCII 字符分类
┌─────────────────────────────────────────────────────────┐
│ ASCII 字符范围 (0-127) │
├─────────────────────────────────────────────────────────┤
│ 0-31 → 控制字符(不可见,如换行、回车等) │
│ 32 → 空格(SP) │
│ 33-126 → 可打印字符(可见) │
│ • 大写字母 A-Z (65-90) │
│ • 小写字母 a-z (97-122) │
│ • 数字 0-9 (48-57) │
│ • 标点符号和特殊符号 │
│ 127 → 删除控制字符(DEL) │
└─────────────────────────────────────────────────────────┘
ASCII 字符的作用
- 统一字符表示标准
计算机只认识二进制0和1,无法直接存储"字符"。ASCII为每个字符分配了一个专属数字编号,使不同厂商的计算机、终端、打印机、通信设备之间能够可靠地交换文本信息。
- 跨设备通信
- 确保不同系统间文本数据的一致性
- 解决早期计算机系统中字符编码混乱的问题
- 成为网络通信、文件存储的基础编码
- 编程与数据处理
- 在C语言等编程语言中,字符变量实际存储的是ASCII码值
- 字符比较、排序等操作基于ASCII码值进行
- 大小写字母编码设计巧妙(仅第6位不同),便于转换
- 控制功能
33个控制字符用于特殊功能,例如:
- 换行符(LF,ASCII 10)
- 回车符(CR,ASCII 13)
- 制表符(TAB,ASCII 9)
- 响铃(BEL,ASCII 7)
ASCII 的局限性
| 限制 | 说明 |
|---|---|
| 仅支持英文 | 主要设计用于英语和西欧语言 |
| 字符数量有限 | 128个字符无法容纳全球所有语言 |
| 不支持中文等 | 无法表示汉字、日文、阿拉伯文等 |
因此,后来出现了扩展ASCII(256个字符)、Unicode(全球统一字符集)和UTF-8等更完善的编码方案来解决多语言支持问题。
总结
ASCII是数字世界字符表达的基石,虽然诞生于60年代,但至今仍是计算机世界的核心基础。它就像盖房子的地基,后续的字符编码标准(如Unicode、UTF-8)都是在其基础上发展和扩展的。理解ASCII对于学习编程、计算机网络、数据处理等领域都非常重要。
encodeURI 与 encodeURIComponent
- encodeURI
const str = "https://www.baidu.com/s?wd=中文";
const result = encodeURI(str);
console.log(result);
// https://www.baidu.com/s?wd=%E4%B8%AD%E6%96%87
为什么要使用 encodeURI() 编码完整 URL?
核心原因
- 支持非 ASCII 字符(中文、emoji 等)
URL 标准(RFC 3986)规定 URL 只能包含 ASCII 字符。如果 URL 中包含中文、特殊符号等,必须编码
// ❌ 不编码 - 可能出现问题
const url = "https://example.com/产品/详情.html";
// 某些浏览器/服务器可能无法正确解析
// ✅ 编码后 - 安全传输
const encoded = encodeURI("https://example.com/产品/详情.html");
// https://example.com/%E4%BA%A7%E5%93%81/%E8%AF%A6%E6%83%85.html
- 保留 URL 结构字符
encodeURI() 的智能之处在于保留 URL 结构必需的字符
| 保留字符 | 作用 |
|---|---|
: | 协议分隔符 (http:) |
/ | 路径分隔符 |
? | 查询参数开始 |
& | 参数分隔符 |
= | 键值分隔符 |
# | 锚点标识 |
const url = "https://example.com/path?name=张三&type=会员#详情";
encodeURI(url);
// https://example.com/path?name=%E5%BC%A0%E4%B8%89&type=%E4%BC%9A%E5%91%98#%E8%AF%A6%E6%83%85
// ✅ 结构字符 : / ? & = # 都保留了
编码决策流程图
URL 包含非 ASCII 字符?
|
┌────────────┴────────────┐
│ 否 │ 是
▼ ▼
可直接使用 是完整 URL 吗?
|
┌──────────┴──────────┐
│ 是 │ 否
▼ ▼
用 encodeURI() 用 encodeURIComponent()
总结对比
| 情况 | 是否需要 encodeURI() | 原因 |
|---|---|---|
| URL 含中文路径 | ✅ 需要 | 非 ASCII 字符需编码 |
| URL 含空格 | ✅ 需要 | 空格会导致解析错误 |
| 纯英文 URL | ❌ 不需要 | 已是有效 ASCII |
| 仅编码参数值 | ❌ 用 encodeURIComponent | 需要编码更多字符 |
| URL 已编码过 | ❌ 不需要 | 避免重复编码 |
最佳实践代码
// 安全编码完整 URL 的工具函数
function safeEncodeURI(url) {
try {
// 检查是否已是有效 URL
new URL(url);
// 如果包含非 ASCII 字符则编码
return /[\u4e00-\u9fa5]/.test(url) ? encodeURI(url) : url;
} catch {
// 无效 URL,返回原值或抛出错误
return encodeURI(url);
}
}
// 使用
const url = safeEncodeURI("https://example.com/产品/列表");
核心原则
完整 URL 含非 ASCII 字符时用 encodeURI(),既保证字符安全传输,又保持 URL 结构完整!🔑
- encodeURIComponent
const str = "https://www.baidu.com/s?wd=中文";
const result = encodeURIComponent(str);
console.log(result);
// https%3A%2F%2Fwww.baidu.com%2Fs%3Fwd%3D%E4%B8%AD%E6%96%87
// 整个URL都被编码了,这样URL失去了有效性
// 正确的做法是:完整URL用 encodeURI,参数值用 encodeURIComponent
// 场景:编码多个参数
const params = {
name: "张三",
email: "test@example.com",
redirect: "https://other.com",
info: {
age: 25,
gender: "male",
address: "北京市海淀区上地十街10号",
},
};
params.info = JSON.stringify(params.info); // 序列化参数值(将对象转换成JSON字符串)
const queryString = Object.keys(params)
.map((key) => `${key}=${encodeURIComponent(params[key])}`)
.join("&");
const str = `https://www.baidu.com/s?${queryString}`;
console.log(str);
// https://www.baidu.com/s?name=%E5%BC%A0%E4%B8%89&email=test%40example.com&redirect=https%3A%2F%2Fother.com&info=%7B%22age%22%3A25%2C%22gender%22%3A%22male%22%2C%22address%22%3A%22%E5%8C%97%E4%BA%AC%E5%B8%82%E6%B5%B7%E6%B7%80%E5%8C%BA%E4%B8%8A%E5%9C%B0%E5%8D%81%E8%A1%9710%E5%8F%B7%22%7D
const passInfo = new URL(str).searchParams;
console.log(passInfo.get("info"));
| 场景 | 推荐方法 |
|---|---|
| 完整URL含中文路径 | encodeURI() |
| URL参数值 | encodeURIComponent() |
| URL参数名 | encodeURIComponent() |
| 已编码的字符串 | 不要再编码 |
记住口诀
完整URL用 encodeURI,参数值用 encodeURIComponent
富文本添加图片预览
- 使用element-ui的图片预览组件,给rich-text类绑定点击事件,使用事件委托的方式获取图片的src,并触发预览事件。
获取富文本所有图片的src
const imgs = document.querySelectorAll(".rich-text img");
const imgSrcs = Array.from(imgs).map((img) => img.src);
this.$nextTick(() => {
const richText = document.querySelector(".rich-text");
richText.addEventListener("click", (event) => {
if (event.target.tagName === "IMG") {
const src = event.target.src;
this.handlePreview(src);
}
});
});
<template>
<div class="rich-text"></div>
</template>
<script>
import { ref } from "vue";
import { ElImage } from "element-plus";
export default {
components: {
ElImage,
},
setup() {
const content = ref("");
const handlePreview = (src) => {
console.log(src);
};
return {
content,
handlePreview,
};
},
};
</script>
<style>
.rich-text {
width: 100%;
height: 300px;
}
</style>
- 自定义图片预览组件
<template>
<div class="rich-text">
<div v-html="content"></div>
<div class="image-preview">
<img :src="previewSrc" alt="" />
</div>
</div>
</template>
<script>
import { ref } from "vue";
export default {
setup() {
const content = ref("");
const previewSrc = ref("");
const handlePreview = (src) => {
previewSrc.value = src;
};
return {
content,
previewSrc,
handlePreview,
};
},
};
</script>
<style>
.rich-text {
width: 100%;
height: 300px;
overflow: auto;
}
.image-preview {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
z-index: 999;
}
