使用SAS令牌上传图片至Azure Blob存储的加载异常问题
问题:Flutter应用通过SAS Token上传Azure Blob返回201但图片无法加载
现象
- Postman测试上传图片至Azure Blob存储,返回201状态码,图片可正常加载
- Flutter应用内执行相同逻辑上传,同样返回201状态码,但上传后的图片无法打开
关联代码
Future<void> uploadImageToAzure() async { await getUploadTokenAPi(); final image = await _signaturePadKey.currentState!.toImage(); final byteData = await image.toByteData(format: ui.ImageByteFormat.png); setState(() {}); bytes = byteData?.buffer.asUint8List(byteData.offsetInBytes,byteData.lengthInBytes); setState(() {}); var headers = { 'x-ms-blob-content-type': 'image/png', 'x-ms-blob-type': 'BlockBlob', 'Content-type': 'application/octet-stream', 'Accept-Encoding': 'gzip, deflate, br', 'Cache-Control': 'max-age=0', }; Dio dio = Dio(); // log("${base64Encode(bytes!)}"); Response response = await dio.put( uploadtokenResponce.data["token"], data: base64Encode(bytes!), options: Options( headers: headers, ), ); if (response.statusCode == 201) { print("================""); log(json.encode(response.headers.map)); print("================""); log("Data : ${response.statusCode}"); } else { print(response.statusMessage); } try {} catch (e) { print('Error uploading image: $e'); } }
注:_signaturePadKey用于获取签名图片
问题定位与修复
核心原因
代码中对图片字节数组执行了base64Encode处理,但Azure Blob存储需要接收原始二进制数据,而非Base64编码后的字符串。Postman上传时直接发送二进制文件,因此正常;Flutter端发送Base64文本,导致Blob存储中保存的是文本内容而非图片二进制,自然无法加载。
修复方案
- 移除
base64Encode,直接将原始字节数组作为请求数据发送 - 清理冗余请求头(
Accept-Encoding、Cache-Control对上传无必要)
修复后代码
Future<void> uploadImageToAzure() async { await getUploadTokenAPi(); final image = await _signaturePadKey.currentState!.toImage(); final byteData = await image.toByteData(format: ui.ImageByteFormat.png); setState(() {}); bytes = byteData?.buffer.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes); setState(() {}); var headers = { 'x-ms-blob-content-type': 'image/png', 'x-ms-blob-type': 'BlockBlob', 'Content-Type': 'application/octet-stream', }; Dio dio = Dio(); try { Response response = await dio.put( uploadtokenResponce.data["token"], data: bytes, // 直接传递原始二进制数据 options: Options(headers: headers), ); if (response.statusCode == 201) { print("================""); log(json.encode(response.headers.map)); print("================""); log("Data : ${response.statusCode}"); } else { print(response.statusMessage); } } catch (e) { print('Error uploading image: $e'); } }
额外验证点
- 确保
bytes不为空,可添加非空判断避免空指针异常 - 检查SAS Token权限,确认包含
Write/Create权限且处于有效期内 - 上传后查看Blob的
Content-Type属性,确认是否为image/png
内容的提问来源于stack exchange,提问作者Ziyad godil
相关产品推荐
相关产品推荐

