JS: 纯前端调用Alist API实现在多种储存下快捷创建目录和上传文件

注意代码并不完善,为了方便演示,账号密码目前是硬编码的,后期请自行调整为安全的环境变量方式,直接上代码

<!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>
暂无评论

发送评论 编辑评论


				
上一篇
下一篇