feat(资源处理): 添加无扩展名和根路径资源的处理逻辑
- 无扩展名资源根据类型自动补全.css或.js扩展名 - 根路径资源使用主机名作为首层目录避免跨域冲突 - 更新README文档说明新增规则
This commit is contained in:
@@ -133,6 +133,13 @@
|
|||||||
- 类型判定:优先扩展名(`.css`/`.js`),其次 `Content-Type`
|
- 类型判定:优先扩展名(`.css`/`.js`),其次 `Content-Type`
|
||||||
- 安全加固:移除 `..` 等越权片段,写入前校验不越界(`server.js:65` 起)
|
- 安全加固:移除 `..` 等越权片段,写入前校验不越界(`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`
|
- 目标路径存在则跳过抓取,响应中返回 `skipped: true`
|
||||||
|
|||||||
83
cache/js/cdn.tailwindcss.com/index.js
vendored
Normal file
83
cache/js/cdn.tailwindcss.com/index.js
vendored
Normal file
File diff suppressed because one or more lines are too long
3
seed.txt
3
seed.txt
@@ -3,4 +3,5 @@
|
|||||||
|
|
||||||
# Bootstrap 5.3.0 样式与脚本
|
# 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/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
|
||||||
|
|||||||
14
server.js
14
server.js
@@ -65,7 +65,7 @@ function resolveTargetPath(urlStr, contentType) {
|
|||||||
const u = new URL(urlStr)
|
const u = new URL(urlStr)
|
||||||
let base = path.basename(u.pathname)
|
let base = path.basename(u.pathname)
|
||||||
if (!base || base === '/') base = 'index'
|
if (!base || base === '/') base = 'index'
|
||||||
const ext = path.extname(base).toLowerCase()
|
let ext = path.extname(base).toLowerCase()
|
||||||
|
|
||||||
let folder
|
let folder
|
||||||
let type
|
let type
|
||||||
@@ -84,6 +84,12 @@ function resolveTargetPath(urlStr, contentType) {
|
|||||||
else if ((contentType || '').split(';')[0].trim() === 'text/css') type = 'css'
|
else if ((contentType || '').split(';')[0].trim() === 'text/css') type = 'css'
|
||||||
else type = 'js'
|
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 → 子目录
|
// 按原URL路径的目录层级保存:/npm/bootstrap@5.3.0/dist/css → 子目录
|
||||||
let subDir = path.dirname(u.pathname)
|
let subDir = path.dirname(u.pathname)
|
||||||
if (subDir === '/' || subDir === '.') subDir = ''
|
if (subDir === '/' || subDir === '.') subDir = ''
|
||||||
@@ -92,7 +98,8 @@ function resolveTargetPath(urlStr, contentType) {
|
|||||||
const safeParts = raw
|
const safeParts = raw
|
||||||
.split('/')
|
.split('/')
|
||||||
.filter(p => p && p !== '..')
|
.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
|
const targetDir = normalized ? path.join(folder, normalized) : folder
|
||||||
|
|
||||||
let fullPath = path.join(targetDir, base)
|
let fullPath = path.join(targetDir, base)
|
||||||
@@ -116,7 +123,8 @@ function sanitizeSubdirFromUrl(urlStr) {
|
|||||||
if (subDir === '/' || subDir === '.') subDir = ''
|
if (subDir === '/' || subDir === '.') subDir = ''
|
||||||
const raw = subDir.replace(/^\/+/, '').replace(/\\+/g, '/')
|
const raw = subDir.replace(/^\/+/, '').replace(/\\+/g, '/')
|
||||||
const safeParts = raw.split('/').filter(p => p && p !== '..')
|
const safeParts = raw.split('/').filter(p => p && p !== '..')
|
||||||
return safeParts.join('/')
|
const joined = safeParts.join('/')
|
||||||
|
return joined ? joined : u.hostname
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user