fix(upload-package): 优化下载前文件资源校验,避免错误页面被下载
在下载安装包前增加 HEAD 请求校验,确认资源存在且为正确的文件类型, 防止后端错误页(如 f.txt)被当作安装包下载。若 HEAD 因 CORS 限制失败, 则回退为直接下载,避免误报。
This commit is contained in:
@@ -8,7 +8,7 @@ VITE_APP_BASE_API=/dev-api
|
||||
# 接口地址
|
||||
# VITE_APP_API_URL=https://api.youlai.tech # 线上
|
||||
# VITE_APP_API_URL=https://api.youlai.tech/v2 # 线上(多租户)
|
||||
VITE_APP_API_URL=http://192.168.5.224:8000 # 本地
|
||||
VITE_APP_API_URL=http://127.0.0.1:8000 # 本地
|
||||
|
||||
|
||||
# 启用 Mock 服务(true:开启 false:关闭)
|
||||
|
||||
3
pnpm-workspace.yaml
Normal file
3
pnpm-workspace.yaml
Normal file
@@ -0,0 +1,3 @@
|
||||
allowBuilds:
|
||||
'@parcel/watcher': true
|
||||
es5-ext: true
|
||||
@@ -341,15 +341,39 @@ function openDetail(item: AppPackage) {
|
||||
detailVisible.value = true;
|
||||
}
|
||||
|
||||
function download(item: AppPackage) {
|
||||
async function download(item: AppPackage) {
|
||||
if (!item.fileUrl) {
|
||||
ElMessage.warning("文件地址缺失");
|
||||
return;
|
||||
}
|
||||
|
||||
const url = withBase(item.fileUrl);
|
||||
const fileName = item.originalName || `${item.packageName}.${item.packageType}`;
|
||||
|
||||
// 先校验资源是否真实存在,避免后端返回的错误页(如 f.txt)被当作文件下载。
|
||||
// 受 CORS 限制时 HEAD 可能失败,此时回退为直接下载(<a> 下载不受 CORS 限制),避免误报。
|
||||
try {
|
||||
const resp = await fetch(url, { method: "HEAD" });
|
||||
if (!resp.ok) {
|
||||
ElMessage.error(`下载失败:资源不存在(${resp.status})`);
|
||||
return;
|
||||
}
|
||||
const contentType = resp.headers.get("Content-Type") || "";
|
||||
// 资源存在但返回的是文本/HTML/JSON 错误页,而不是实际安装包
|
||||
if (/(text\/html|text\/plain|application\/json)/i.test(contentType)) {
|
||||
ElMessage.error("下载失败:资源未找到或链接无效");
|
||||
return;
|
||||
}
|
||||
} catch {
|
||||
// HEAD 不可达(多为跨域限制),直接走原生下载兜底
|
||||
}
|
||||
|
||||
const a = document.createElement("a");
|
||||
a.href = withBase(item.fileUrl);
|
||||
a.download = item.originalName || `${item.packageName}.${item.packageType}`;
|
||||
a.href = url;
|
||||
a.download = fileName;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
}
|
||||
|
||||
async function handleDelete(item: AppPackage) {
|
||||
|
||||
Reference in New Issue
Block a user