注意代码并不完善,为了方便演示,账号密码目前是硬编码的,后期请自行调整为安全的环境变量方式,直接上代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Alist File Upload</title>
</head>
<body>
<input type="file" id="fileInput" multiple />
<script>
// 替换为您的Alist域名
const ALIST_BASE_URL = "https://example.com";
// 替换为您的用户名
const USERNAME = "admin";
// 替换为您的密码
const PASSWORD = "123456";
// 替换为文件上传到的文件目录,每次上传都会以当前时间命名创建文件夹最后上传到新文件夹中
const UPLOAD_ROOT_FOLDER = "测试文件夹/子文件夹";
// 登录
async function login() {
const response = await fetch(`${ALIST_BASE_URL}/api/auth/login`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ Username: USERNAME, Password: PASSWORD }),
});
const data = await response.json();
if (data.code !== 200) {
throw new Error("Login failed: " + data.message);
}
return data.data.token;
}
// 创建文件夹
async function createFolder(token) {
const folderName = new Date()
.toISOString()
.replace(/[-:.TZ]/g, "")
.substring(0, 14);
const response = await fetch(`${ALIST_BASE_URL}/api/fs/mkdir`, {
method: "POST",
headers: {
Authorization: token,
"Content-Type": "application/json",
},
body: JSON.stringify({ path: `${UPLOAD_ROOT_FOLDER}/${folderName}` }),
});
const data = await response.json();
if (data.code !== 200) {
throw new Error("Failed to create folder: " + data.message);
}
return `${UPLOAD_ROOT_FOLDER}/${folderName}`;
}
// 上传文件
async function uploadFile(token, folderPath, file, retryCount = 3) {
const encodedFolderPath = encodeURIComponent(folderPath).replace(
/%2F/g,
"/"
);
const encodedFileName = encodeURIComponent(file.name).replace(
/%2F/g,
"/"
);
const encodedFilePath = `${encodedFolderPath}/${encodedFileName}`;
const formData = new FormData();
formData.append("file", file);
try {
const response = await fetch(`${ALIST_BASE_URL}/api/fs/form`, {
method: "PUT",
headers: {
Authorization: token,
"file-path": encodedFilePath,
},
body: formData,
});
const data = await response.json();
if (data.code !== 200) {
throw new Error("Failed to upload file: " + data.message);
}
console.log("上传成功: ", file.name);
} catch (error) {
if (retryCount > 0) {
console.log(
`Retrying to upload file: ${file.name}, attempts left:${retryCount}`
);
await uploadFile(token, folderPath, file, retryCount - 1);
} else {
throw error;
}
}
}
// 处理文件上传
async function handleFileUpload() {
try {
const token = await login();
const folderPath = await createFolder(token);
const files = document.getElementById("fileInput").files;
// 限制并发上传数量
const maxConcurrentUploads = 3;
for (let i = 0; i < files.length; i += maxConcurrentUploads) {
const chunk = Array.from(files).slice(i, i + maxConcurrentUploads);
await Promise.all(
chunk.map((file) => uploadFile(token, folderPath, file))
);
}
console.log("All files uploaded successfully.");
} catch (error) {
console.error("Error:", error);
alert(error.message);
}
}
// 绑定事件监听器
document
.getElementById("fileInput")
.addEventListener("change", handleFileUpload);
</script>
</body>
</html>