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

使用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("================&quot;");
    log(json.encode(response.headers.map));
    print("================&quot;");
    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存储中保存的是文本内容而非图片二进制,自然无法加载。

修复方案

  1. 移除base64Encode,直接将原始字节数组作为请求数据发送
  2. 清理冗余请求头(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("================&quot;");
      log(json.encode(response.headers.map));
      print("================&quot;");
      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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 11:17:32