修改下载页面渲染

This commit is contained in:
zyj
2025-11-24 18:59:19 +08:00
parent 51cfd5cf21
commit 65d4d458d0
10 changed files with 2328 additions and 111 deletions

384
HTML_PATH_REPLACE.md Normal file
View File

@@ -0,0 +1,384 @@
# HTML 资源路径替换功能说明
## 📋 功能概述
在下载网站时,自动将 HTML 文件中的所有资源绝对路径转换为相对路径,使得离线浏览时资源能够正确加载。
---
## ✨ 支持的资源类型
### 1. **CSS 样式表**
```html
<!-- 替换前 -->
<link href="https://example.com/css/style.css" rel="stylesheet">
<!-- 替换后 -->
<link href="./css/style.css" rel="stylesheet">
```
### 2. **JavaScript 脚本**
```html
<!-- 替换前 -->
<script src="https://example.com/js/app.js"></script>
<!-- 替换后 -->
<script src="./js/app.js"></script>
```
### 3. **图片资源**
```html
<!-- 替换前 -->
<img src="https://example.com/images/logo.png" alt="Logo">
<!-- 替换后 -->
<img src="./images/logo.png" alt="Logo">
```
### 4. **视频资源**
```html
<!-- 替换前 -->
<video src="https://example.com/videos/demo.mp4"></video>
<source src="https://example.com/videos/demo.webm">
<!-- 替换后 -->
<video src="./videos/demo.mp4"></video>
<source src="./videos/demo.webm">
```
### 5. **音频资源**
```html
<!-- 替换前 -->
<audio src="https://example.com/audio/music.mp3"></audio>
<!-- 替换后 -->
<audio src="./audio/music.mp3"></audio>
```
### 6. **CSS 中的 URL**
```css
/* 替换前 */
background-image: url('https://example.com/images/bg.jpg');
background: url("https://example.com/images/pattern.png");
background: url(https://example.com/images/texture.jpg);
/* 替换后 */
background-image: url('./images/bg.jpg');
background: url("./images/pattern.png");
background: url(./images/texture.jpg);
```
---
## 🔧 技术实现
### 核心函数
#### 1. `replaceHTMLResourcePaths()`
主函数,负责替换 HTML 中的所有资源路径。
```go
func replaceHTMLResourcePaths(htmlContent string, baseURL string) string {
// 解析基础 URL
// 使用正则表达式匹配各种资源标签
// 调用 convertToRelativePath 转换每个 URL
// 返回修改后的 HTML
}
```
#### 2. `convertToRelativePath()`
将绝对 URL 转换为相对路径。
**判断逻辑**
- ✅ 只替换同域名的资源
- ❌ 跳过外部域名资源
- ❌ 跳过 data:、javascript:、mailto: 等协议
- ❌ 跳过已经是相对路径的资源
```go
func convertToRelativePath(resourceURL, baseURL, baseHost, baseScheme, basePath string) string {
// 1. 验证 URL 类型
// 2. 检查是否同域名
// 3. 计算相对路径
// 4. 返回转换结果
}
```
#### 3. `calculateRelativePath()`
计算两个路径之间的相对路径。
**示例**
```go
basePath := "/pages/about/"
targetPath := "/css/style.css"
// 结果:../../css/style.css
```
---
## 📊 路径转换示例
### 示例 1同级目录
```
当前页面https://example.com/index.html
资源路径https://example.com/style.css
转换结果:./style.css
```
### 示例 2子目录
```
当前页面https://example.com/index.html
资源路径https://example.com/css/main.css
转换结果:./css/main.css
```
### 示例 3上级目录
```
当前页面https://example.com/pages/about.html
资源路径https://example.com/css/style.css
转换结果:../css/style.css
```
### 示例 4深层嵌套
```
当前页面https://example.com/blog/2024/11/post.html
资源路径https://example.com/images/logo.png
转换结果:../../../images/logo.png
```
### 示例 5外部资源不替换
```
当前页面https://example.com/index.html
资源路径https://cdn.example.com/jquery.js
转换结果https://cdn.example.com/jquery.js保持不变
```
---
## 🚫 不会被替换的资源
### 1. **Data URL**
```html
<img src="data:image/png;base64,iVBORw0KG...">
<!-- 保持不变 -->
```
### 2. **JavaScript 伪协议**
```html
<a href="javascript:void(0)">Click</a>
<!-- 保持不变 -->
```
### 3. **锚点链接**
```html
<a href="#section1">Go to Section 1</a>
<!-- 保持不变 -->
```
### 4. **外部域名资源**
```html
<script src="https://cdn.jsdelivr.net/npm/vue@3"></script>
<!-- 保持不变(不同域名)-->
```
### 5. **已经是相对路径**
```html
<img src="./images/photo.jpg">
<link href="../css/style.css">
<!-- 保持不变 -->
```
---
## 🎯 使用场景
### 1. **离线浏览**
下载整站后,可以在没有网络的情况下正常浏览,所有资源都能正确加载。
### 2. **网站备份**
保存网站的完整副本,包括所有页面和资源,路径关系正确。
### 3. **网站迁移**
将网站从一个域名迁移到另一个域名,资源路径自动适配。
### 4. **本地开发**
在本地环境测试网站,无需配置虚拟主机。
---
## 🔍 处理流程
```
1. 下载 HTML 文件
2. 读取 HTML 内容
3. 解析基础 URL当前页面地址
4. 使用正则表达式匹配资源标签
├─ <link href="...">
├─ <script src="...">
├─ <img src="...">
├─ <video src="...">
├─ <audio src="...">
└─ url(...)
5. 对每个匹配项:
├─ 提取 URL
├─ 判断是否需要替换
├─ 计算相对路径
└─ 替换原 URL
6. 保存修改后的 HTML 文件
```
---
## 📝 正则表达式说明
### CSS 链接
```go
regexp: `(<link[^>]*?href=[\"'])([^\"']+)([\"'][^>]*?>)`
匹配: <link ... href="URL" ...>
```
### JavaScript 脚本
```go
regexp: `(<script[^>]*?src=[\"'])([^\"']+)([\"'][^>]*?>)`
匹配: <script ... src="URL" ...>
```
### 图片
```go
regexp: `(<img[^>]*?src=[\"'])([^\"']+)([\"'][^>]*?>)`
匹配: <img ... src="URL" ...>
```
### 视频和 Source
```go
regexp: `(<(?:video|source)[^>]*?src=[\"'])([^\"']+)([\"'][^>]*?>)`
匹配: <video src="URL"> <source src="URL">
```
### CSS URL
```go
regexp: `(url\\([\"']?)([^\"')]+)([\"']?\\))`
匹配: url("URL") url('URL') url(URL)
```
---
## ⚠️ 注意事项
### 1. **同域名限制**
只替换与当前页面同域名的资源,确保不破坏 CDN 等外部资源。
### 2. **编码问题**
假设 HTML 文件使用 UTF-8 编码,其他编码可能需要额外处理。
### 3. **动态加载**
通过 JavaScript 动态加载的资源可能无法自动替换,需要手动处理。
### 4. **绝对路径限制**
页面内如果使用了 `<base>` 标签,可能影响相对路径的解析。
### 5. **特殊字符**
URL 中包含特殊字符(如空格、中文)可能需要 URL 编码。
---
## 🔄 完整示例
### 原始 HTML
```html
<!DOCTYPE html>
<html>
<head>
<link href="https://example.com/css/style.css" rel="stylesheet">
<script src="https://example.com/js/app.js"></script>
<style>
body { background: url('https://example.com/images/bg.jpg'); }
</style>
</head>
<body>
<img src="https://example.com/images/logo.png" alt="Logo">
<video src="https://example.com/videos/intro.mp4"></video>
<script src="https://cdn.example.com/library.js"></script>
</body>
</html>
```
### 转换后 HTML
```html
<!DOCTYPE html>
<html>
<head>
<link href="./css/style.css" rel="stylesheet">
<script src="./js/app.js"></script>
<style>
body { background: url('./images/bg.jpg'); }
</style>
</head>
<body>
<img src="./images/logo.png" alt="Logo">
<video src="./videos/intro.mp4"></video>
<script src="https://cdn.example.com/library.js"></script>
<!-- 注意:外部 CDN 资源保持不变 -->
</body>
</html>
```
---
## 🚀 性能优化
### 1. **正则表达式预编译**
可以将正则表达式编译为全局变量,避免重复编译:
```go
var (
cssRegex = regexp.MustCompile(`(<link[^>]*?href=[\"'])([^\"']+)([\"'][^>]*?>)`)
scriptRegex = regexp.MustCompile(`(<script[^>]*?src=[\"'])([^\"']+)([\"'][^>]*?>)`)
// ... 其他正则
)
```
### 2. **批量替换**
使用 `strings.Replacer` 进行批量替换可能更高效(但需要先收集所有需要替换的 URL
### 3. **HTML 解析器**
对于复杂的 HTML可以考虑使用 `golang.org/x/net/html` 进行 DOM 解析,更准确但性能稍低。
---
## 🐛 调试日志
函数会输出详细的转换日志:
```
路径替换: https://example.com/css/style.css -> ./css/style.css
路径替换: https://example.com/images/logo.png -> ./images/logo.png
路径替换: https://example.com/js/app.js -> ./js/app.js
```
可以通过日志查看哪些资源被替换,哪些被跳过。
---
## 📌 总结
HTML 资源路径替换功能使得下载的网站能够:
**离线完整浏览** - 所有资源路径正确
**保持原有结构** - 目录关系不变
**智能判断** - 只替换需要替换的资源
**保护外部资源** - CDN 等外部资源保持不变
**性能优化** - 使用正则批量处理
这使得整站下载功能更加完善和实用!