如何使用 Next.js 处理要下载的多个图像?

How to handle multiple images to download using Next.js?

提问人:Bruno Rodrigues 提问时间:11/15/2023 最后编辑:Bruno Rodrigues 更新时间:11/15/2023 访问量:26

问:

我有一个名为/photos的路由,它支持通过“page”查询参数进行分页,并允许我使用“pageSize”指定每页的照片数量。它返回一组照片和可用照片的总数。

This is my api route
/photos?cameraId=580&start=2023-10-29&end=2023-10-30&beginTime=18:00&endTime=19:00&Page=1&PageSize=10
This is my return object
{
    "photos": [
        {  "urlPreview": "https://example.com/random-preview-url"  }
        ...
    ],
    "total": 239
}

现在,我需要在我的页面上实现一个按钮,单击该按钮后,将开始下载这些照片。照片总数约为 12K,这显然需要一些时间和处理时间。

有人建议我使用 localStorage 以增量方式保存照片,然后将它们全部压缩供用户下载。

但是,我不知道如何实现这一点,因为我以前从未做过这样的事情。有人可以指导我如何进行吗?

我试图像这样使用我的downloadMassivePhotos函数下载

import JSZip from 'jszip';
import { saveAs } from 'file-saver';

export const downloadMassivePhotos = async (
  cameraId,
  start,
  end,
  beginTime,
  endTime,
) => {
  const zip = new JSZip();
  const maxConcurrentDownloads = 20;
  let activeDownloads = 0;

  try {
    const { photos } = await fetchAPI({
      path: 'photos',
      query: { cameraId, start, end, beginTime, endTime },
    });

    for (const photo of photos) {
      while (activeDownloads >= maxConcurrentDownloads) {
        await new Promise((resolve) => setTimeout(resolve, 1000));
      }

      activeDownloads++;

      fetchAndZipPhoto(photo, zip)
        .catch((error) => {
          console.error(`Error downloading photo ${photo.id}:`, error);
        })
        .finally(() => {
          activeDownloads--;
        });
    }

    while (activeDownloads > 0) {
      await new Promise((resolve) => setTimeout(resolve, 1000));
    }

    const content = await zip.generateAsync({ type: 'blob' });
    saveAs(content, 'photos.zip');
  } catch (error) {
    console.error(error);
  }
};

const fetchAndZipPhoto = async (photo, zip) => {
  const { urlImage, id } = photo;
  const response = await fetch(urlImage);
  if (!response.ok) {
    throw new Error(`HTTP error! Status: ${response.status}`);
  }
  const blob = await response.blob();
  zip.file(`${id}.jpg`, blob, { binary: true });
};

这是我的获取方法

export const api = axios.create({
  baseURL: process.env.NEXT_PUBLIC_API_HOST,
});

export const fetchAPI = async <T>({ path, query, context }: FetchAPI) => {
  const session = await getSession(context);

  const { data, status } = await api.get<T>(`/${path}`, {
    headers: { Authorization: `Bearer ${session?.token}` },
    params: query,
  });

  if (!data && status !== 200) {
    throw new Error(`API call to ${path} failed.`);
  }

  return data;
};
JavaScript 下载 jszip 文件保护程序.js

评论

0赞 Sam Hughes 11/15/2023
这意味着获取二进制流并将整数数组或 base64 编码的字节保存到活动会话存储中的变量中。这允许您将数据服务器传输到客户端,将原始数据累积为文件句柄,写入 zip 文件句柄(也映射到会话存储),然后将该文件句柄“下载”到实际的客户端存储中。MDN 上的会话存储:developer.mozilla.org/en-US/docs/Web/API/Storage,这里有一个关于使用 zip.js 的 SO 问题:stackoverflow.com/questions/17510979/...

答: 暂无答案