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
相关产品推荐
相关产品推荐

