You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Google Drive API分页异常:仅两页时上页正常,多页失效

问题分析与解决方案

问题根源

  1. 原上一页逻辑错误:点击上一页时直接调用listFiles(folderId)(不传pageToken),仅适用于从第2页返回第1页的场景。当页数超过2页时,从第3页返回第2页需要传入第2页对应的pageToken(即第1页的nextPageToken),而非直接传null,这导致回到第2页后无法继续返回第1页。
  2. 令牌数组未正确维护:尝试用数组存储令牌时,没有跟踪当前页面在历史中的位置,导致后退时无法正确匹配对应的上一页令牌。

解决方案:维护分页历史栈

通过维护一个页面令牌历史栈和当前页面索引,精准控制前后翻页的令牌传递:

1. 初始化全局状态变量

// 存储所有访问过的页面令牌,索引0对应第1页(token为null)
let pageTokenHistory = [null];
// 当前页面在历史栈中的索引,初始为第1页
let currentPageIndex = 0;

2. 修改listFiles函数的翻页逻辑

async function listFiles(folderId, pageToken = null) {
  $('#table_content').empty();
  $('#table_content').remove();
  isListFilesInProgress = true;
  $('#show_files_button').prop('disabled', true);

  const request = {
    q: `'${folderId}' in parents`,
    pageSize: 10,
    fields: 'nextPageToken, files(id, name, mimeType, thumbnailLink, webContentLink, modifiedTime)',
    pageToken: pageToken,
  };

  gapi.client.drive.files
    .list(request)
    .then(function (response) {
      console.log(response);
      var files = response.result.files;
      if (files && files.length > 0) {
        // 生成表格的代码保持不变,此处省略重复代码
        var table = document.createElement('table');
        table.classList.add('table', 'table-striped');
        table.id = 'table_content';

        var thead = document.createElement('thead');
        var headerRow = document.createElement('tr');
        var header1 = document.createElement('th');
        header1.textContent = 'Thumbnail';
        var header2 = createSortableHeader('Name', 'name');
        var header3 = createSortableHeader('Type', 'mimeType');
        var header4 = createSortableHeader('Last Updated', 'modifiedTime');
        var header5 = document.createElement('th');
        header5.textContent = 'Download';

        headerRow.appendChild(header1);
        headerRow.appendChild(header2);
        headerRow.appendChild(header3);
        headerRow.appendChild(header4);
        headerRow.appendChild(header5);
        thead.appendChild(headerRow);
        table.appendChild(thead);

        var tbody = document.createElement('tbody');
        for (var i = 0; i < files.length; i++) {
          (function (file) {
            var fileName = file.name;
            var mimeType = file.mimeType;
            var thumbnailLink = file.thumbnailLink;
            var downloadLink = file.webContentLink;
            var lastUpdated = new Date(file.modifiedTime).toLocaleString();
            var fileId = file.id;

            var row = document.createElement('tr');

            var thumbnailCell = createThumbnailCell(thumbnailLink, mimeType, fileId);
            row.appendChild(thumbnailCell);

            var nameCell = document.createElement('td');
            nameCell.textContent = fileName;
            row.appendChild(nameCell);

            var typeCell = document.createElement('td');
            typeCell.textContent = mimeType;
            row.appendChild(typeCell);

            var lastUpdatedCell = document.createElement('td');
            lastUpdatedCell.textContent = lastUpdated;
            row.appendChild(lastUpdatedCell);

            if (mimeType != 'application/vnd.google-apps.folder') {
              var downloadCell = document.createElement('td');
              var downloadLinkElem = document.createElement('a');
              downloadLinkElem.href = downloadLink;
              downloadLinkElem.textContent = 'Download';
              downloadLinkElem.classList.add('btn', 'btn-primary');
              downloadLinkElem.target = '_blank';
              downloadCell.appendChild(downloadLinkElem);
              row.appendChild(downloadCell);
            }

            if (mimeType === 'application/vnd.google-apps.folder') {
              row.classList.add('folder-row');
              row.addEventListener('click', function () {
                var folderId = file.id;
                // 进入新文件夹时重置分页历史
                pageTokenHistory = [null];
                currentPageIndex = 0;
                listFiles(folderId);
              });
            }

            tbody.appendChild(row);
          })(files[i]);
        }

        table.appendChild(tbody);
        document.getElementById('content').appendChild(table);

        // 移除旧的翻页按钮
        $('.next-page-button').remove();
        $('.previous-page-button').remove();

        const nextPageToken = response.result.nextPageToken;
        // 添加下一页按钮
        if (nextPageToken) {
          const nextPageButton = document.createElement('button');
          nextPageButton.textContent = 'Next Page';
          nextPageButton.classList.add('btn', 'btn-primary', 'next-page-button');
          nextPageButton.addEventListener('click', function () {
            // 若当前是历史栈最后一页,将新令牌加入栈
            if (currentPageIndex === pageTokenHistory.length - 1) {
              pageTokenHistory.push(nextPageToken);
            }
            currentPageIndex++;
            listFiles(folderId, nextPageToken);
          });
          document.getElementById('content').appendChild(nextPageButton);
        }

        // 添加上一页按钮:仅当前索引大于0时显示(非第一页)
        if (currentPageIndex > 0) {
          const previousPageButton = document.createElement('button');
          previousPageButton.textContent = 'Previous Page';
          previousPageButton.classList.add('btn', 'btn-primary', 'previous-page-button');
          previousPageButton.addEventListener('click', function () {
            currentPageIndex--;
            // 从历史栈中取出上一页的令牌
            const prevToken = pageTokenHistory[currentPageIndex];
            listFiles(folderId, prevToken);
          });
          document.getElementById('content').appendChild(previousPageButton);
        }
      }
    })
    .finally(function () {
      isListFilesInProgress = false;
      $('#show_files_button').prop('disabled', false);
    });
}

3. 关键修改说明

  • 历史栈维护:点击下一页时,若当前是历史栈的最后一页,将新的nextPageToken加入栈;若从中间页前进(如从第2页回到第3页),直接使用栈中已有的令牌。
  • 上一页逻辑:点击上一页时,将当前索引减1,从历史栈中取出对应索引的令牌,确保回到正确的上一页。
  • 文件夹导航重置:进入新文件夹时重置历史栈和索引,避免不同文件夹的分页令牌混淆。

内容的提问来源于stack exchange,提问作者Laimonas Rupeika

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 10:59:52