如何通过GraphQL mutation上传Base64格式图片?
问题
将设备相机拍摄的图片转换为带前缀的Base64字符串:
data:image/jpeg;base64,/9j/4AAQ........
执行GraphQL mutation时收到错误:Variable "$file" got invalid value,精简代码如下:
variables = { file: base64, }; const { mutate } = useMutation( UPLOAD_FILE, () => ({ variables }));
请问如何上传这张图片?Base64是正确的类型吗?发送到服务器前是否需要处理或提取?如何通过GraphQL mutation上传Base64格式内容?
解决方案
核心问题:你传的Base64格式不对
直接传递带data:image/jpeg;base64,前缀的完整URI字符串,是导致变量错误的主要原因——绝大多数GraphQL接口要求的是纯Base64数据部分,而非完整的Data URI格式。
具体处理步骤
1. 提取纯Base64数据
先把前缀剥离,只保留逗号后的内容:
// 假设base64是你拿到的完整Data URI字符串 const pureBase64 = base64.split(',')[1]; const variables = { file: pureBase64, }; const { mutate } = useMutation(UPLOAD_FILE, () => ({ variables }));
2. 确认GraphQL变量的预期类型
根据你的UPLOAD_FILE mutation定义,分两种情况处理:
- 如果
$file类型是String:
传递提取后的纯Base64字符串即可,这是最直接的方式。 - 如果
$file类型是标准Upload标量:Upload类型是为二进制文件上传设计的(对应multipart/form-data请求),不能直接传Base64。需要把Base64转成File对象:// 先提取纯Base64 const pureBase64 = base64.split(',')[1]; // 转成Blob const blob = b64toBlob(pureBase64, 'image/jpeg'); // 转成File对象 const file = new File([blob], 'camera-photo.jpg', { type: 'image/jpeg' }); // 再传入mutation const variables = { file }; const { mutate } = useMutation(UPLOAD_FILE, () => ({ variables })); // 辅助函数:Base64转Blob function b64toBlob(b64Data, contentType = '', sliceSize = 512) { const byteCharacters = atob(b64Data); const byteArrays = []; for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) { const slice = byteCharacters.slice(offset, offset + sliceSize); const byteNumbers = new Array(slice.length); for (let i = 0; i < slice.length; i++) { byteNumbers[i] = slice.charCodeAt(i); } const byteArray = new Uint8Array(byteNumbers); byteArrays.push(byteArray); } return new Blob(byteArrays, { type: contentType }); }
3. 验证服务器端要求
如果提取纯Base64后仍报错,去查看服务器端的mutation文档,确认file变量的预期格式——少数服务器可能接受带前缀的Data URI,但这种情况非常少见。
内容的提问来源于stack exchange,提问作者Ali Seivani
相关产品推荐
相关产品推荐

