feat(资源处理): 添加无扩展名和根路径资源的处理逻辑

- 无扩展名资源根据类型自动补全.css或.js扩展名
- 根路径资源使用主机名作为首层目录避免跨域冲突
- 更新README文档说明新增规则
This commit is contained in:
2025-12-12 00:11:19 +08:00
parent 471ed156af
commit eaf547981b
4 changed files with 103 additions and 4 deletions

View File

@@ -133,6 +133,13 @@
- 类型判定:优先扩展名(`.css`/`.js`),其次 `Content-Type`
- 安全加固:移除 `..` 等越权片段,写入前校验不越界(`server.js:65` 起)
### 规则补充(无扩展名与根路径资源)
- 无扩展名的资源将根据类型自动补全扩展名:`text/css` → `.css`、`application/text-javascript`/`text/javascript` → `.js`
- 根路径资源(如 `https://cdn.tailwindcss.com`)为避免跨域冲突,将以主机名作为首层目录:
- 本地保存:`cache/js/cdn.tailwindcss.com/index.js`
- 对外访问:`/js/cdn.tailwindcss.com/index.js`
## 去重策略
- 目标路径存在则跳过抓取,响应中返回 `skipped: true`

83
cache/js/cdn.tailwindcss.com/index.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -3,4 +3,5 @@
# Bootstrap 5.3.0 样式与脚本
https://cdn.jsdmirror.com/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css
https://cdn.jsdmirror.com/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js
https://cdn.jsdmirror.com/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js
https://cdn.tailwindcss.com

View File

@@ -65,7 +65,7 @@ function resolveTargetPath(urlStr, contentType) {
const u = new URL(urlStr)
let base = path.basename(u.pathname)
if (!base || base === '/') base = 'index'
const ext = path.extname(base).toLowerCase()
let ext = path.extname(base).toLowerCase()
let folder
let type
@@ -84,6 +84,12 @@ function resolveTargetPath(urlStr, contentType) {
else if ((contentType || '').split(';')[0].trim() === 'text/css') type = 'css'
else type = 'js'
// 无扩展名时根据判定类型补全扩展名确保同一URL在抓取前后路径一致
if (!ext) {
if (type === 'css') { base = `${base}.css`; ext = '.css' }
else { base = `${base}.js`; ext = '.js' }
}
// 按原URL路径的目录层级保存/npm/bootstrap@5.3.0/dist/css → 子目录
let subDir = path.dirname(u.pathname)
if (subDir === '/' || subDir === '.') subDir = ''
@@ -92,7 +98,8 @@ function resolveTargetPath(urlStr, contentType) {
const safeParts = raw
.split('/')
.filter(p => p && p !== '..')
const normalized = safeParts.join('/')
let normalized = safeParts.join('/')
if (!normalized) normalized = u.hostname
const targetDir = normalized ? path.join(folder, normalized) : folder
let fullPath = path.join(targetDir, base)
@@ -116,7 +123,8 @@ function sanitizeSubdirFromUrl(urlStr) {
if (subDir === '/' || subDir === '.') subDir = ''
const raw = subDir.replace(/^\/+/, '').replace(/\\+/g, '/')
const safeParts = raw.split('/').filter(p => p && p !== '..')
return safeParts.join('/')
const joined = safeParts.join('/')
return joined ? joined : u.hostname
}
/**