如何通过Flutter GraphQL向Strapi CMS上传文件至Cloudinary?
使用GraphQL向Strapi上传文件的正确方式及常见问题解答
一、正确的GraphQL突变语法
你之前的突变写法存在两个核心错误:
- 错误使用
upload(file: ...)嵌套语法,Strapi的GraphQL媒体字段直接接受Upload类型变量 - 尝试将
Uint8List二进制数据直接嵌入查询字符串,不符合GraphQL文件上传规范(必须用multipart请求)
正确的突变应使用变量定义,直接将媒体字段绑定到Upload类型变量:
mutation CreateProject( $name: String!, $description: String!, $completed: Boolean!, $startDate: DateTime!, $endDate: DateTime!, $projectLogo: Upload!, $publishedAt: DateTime! ) { createProject(data: { title: $name, description: $description, completed: $completed, start_date: $startDate, end_date: $endDate, project_logo: $projectLogo, publishedAt: $publishedAt }) { data { id attributes { title description completed start_date end_date } } } }
二、Flutter中的具体实现步骤
Flutter的graphql插件支持multipart文件上传,需要将Uint8List转换为MultipartFile,通过插件的uploads参数传递,而非直接在variables里赋值:
// 假设已获取到图片的Uint8List数据imageData和文件名fileName final multipartFile = MultipartFile.fromBytes( 'variables.projectLogo', // 对应突变中的变量路径 imageData!, filename: fileName, // 例如"project-logo.png" ); // 构建突变选项 final mutationOptions = MutationOptions( document: gql(/* 上面的GraphQL突变字符串 */), variables: { 'name': name, 'description': description, 'completed': completed, 'startDate': startDate.toIso8601String(), 'endDate': endDate.toIso8601String(), 'publishedAt': '${publishedAt}Z', // 注意:不要在这里添加projectLogo变量,文件通过uploads参数传递 }, uploads: [multipartFile], // 传递文件 ); // 执行突变 final result = await graphQLClient.mutate(mutationOptions);
三、关于Cloudinary的疑问解答
不需要手动将图片上传到Cloudinary。你已配置Strapi使用Cloudinary作为媒体存储,文件通过GraphQL上传到Strapi后,Strapi会自动完成:
- 接收上传的文件
- 将文件上传到Cloudinary
- 把Cloudinary返回的文件元数据(如ID、访问URL等)保存到Strapi数据库中
你只需专注于向Strapi发送正确的GraphQL上传请求即可,无需额外调用Cloudinary的API。
四、错误原因分析
你遇到的Expected an object field name错误,是因为:
- 错误使用
upload(file: $projectLogo)的嵌套语法,Strapi不要求这种调用方式 - 直接将
Uint8List二进制数组插值到查询字符串中,导致GraphQL解析器无法识别该格式的参数
内容的提问来源于stack exchange,提问作者Frank Mwale
相关产品推荐
相关产品推荐

