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

Flutter Web应用中Google Drive API缩略图链接偶发CORS头缺失问题

问题:Google Drive appDataFolder缩略图偶尔出现CORS头缺失问题

我了解CORS相关知识,也知晓存在同类问题,但现有解决方案均不适用于我的应用场景。我的Flutter Web应用通过Google Drive API将图片上传至appDataFolder,展示上传图片的缩略图时偶尔会出现CORS问题:部分请求响应头包含Access-Control-Allow-Origin: *可正常加载,另一部分则缺失该头导致加载失败。点击刷新按钮重新调用fetchTokens函数(Token为产品名称,与访问令牌无关)重新获取并渲染缩略图时,失败的图片会变为另一组,每个缩略图约有50%概率出现CORS头缺失情况。已排除访问权限过期可能(重新请求后原本失败的图片可能正常显示),请问该问题的原因是什么?

相关代码

final scopes = [DriveApi.driveAppdataScope];

class DriveServiceApi {
  DriveServiceApi();

  Future<auth.AuthClient> getClient() async {
    final client = await googleSignIn.authenticatedClient();
    if (client == null) {
      throw Exception('Client is null');
    }
    return client;
  }

  Future<List<Token>> fetchTokens() async {
    final isAuthorised = await googleSignIn.canAccessScopes(scopes);
    if (!isAuthorised) {
      await googleSignIn.requestScopes(scopes);
    }
    final client = await getClient();
    final api = DriveApi(client);

    final files = await api.files.list(
      spaces: 'appDataFolder',
      $fields:
          'files(id, name, properties, appProperties, webContentLink, thumbnailLink, createdTime, modifiedTime)',
    );
    return files.files!.map((file) {
      if (file.thumbnailLink != null) {
        file.thumbnailLink = file.thumbnailLink!.replaceAll('=s220', '=s300');
      }
      return Token(
        file: file,
        metadata: const TokenMetadata(),
      );
    }).toList();
  }

  Future<Token> addToken(XFile image) async {
    final client = await getClient();
    final api = DriveApi(client);
    final extension = image.path.split('.').last;
    return api.files
        .create(
      File(
        name: 'token_${DateTime.now().millisecondsSinceEpoch}',
        parents: ['appDataFolder'],
      ),
      $fields:
          'id, name, properties, appProperties, webContentLink, thumbnailLink, createdTime, modifiedTime',
      uploadMedia:
          Media(image.openRead(), null, contentType: 'image/$extension'),
      uploadOptions: ResumableUploadOptions(
        numberOfAttempts: 5,
      ),
    )
        .then((file) {
          debugPrint("Uploaded File ID: ${file.id}");
      return Token(
        file: file,
        metadata: TokenMetadata.fromJson(file.properties ?? {}),
      );
    });
  }

  Future<bool> deleteToken(Token token) async {
    final client = await getClient();
    final api = DriveApi(client);
    return api.files
        .delete(token.file.id!)
        .then((_) => true)
        .catchError((_) => false);
  }
}

原因分析

  • CDN节点配置不一致:Google Drive的缩略图由多个CDN节点提供服务,不同节点对CORS响应头的配置存在差异。部分节点会自动添加Access-Control-Allow-Origin: *,而另一些节点未配置该头,导致请求不同节点时出现随机的CORS失败。
  • 缩略图链接的无授权特性:虽然你通过OAuth获取了driveAppdataScope权限,但thumbnailLink本身是公开可访问的链接,请求时无需携带授权令牌。当请求被路由到未配置CORS的节点时,浏览器就会触发跨域拦截。
  • 请求路由的随机性:刷新页面重新请求时,浏览器会重新选择CDN节点,每次请求的节点可能不同,因此失败的图片会随机切换,呈现出约50%的概率性失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 04:00:06