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

基于Go+Gin的Azure Blob上传API报InvalidUri错误排查

Azure Blob上传API InvalidUri错误原因及修复

问题描述

使用Go语言结合Gin框架开发了Azure Storage Blob上传API,代码如下:

package main

import (
    "context"
    "fmt"
    "log"
    "net/http"
    "net/url"

    "github.com/Azure/azure-storage-blob-go/azblob"
    "github.com/gin-gonic/gin"
)

func main() {
    router := gin.Default()

    router.POST("/upload", func(c *gin.Context) {
        accountName := "blablabla"
        accountKey := "mykey"
        containerName := "testblabla"
        blobName := c.PostForm("blobName")

        credential, err := azblob.NewSharedKeyCredential(accountName, accountKey)
        if err != nil {
            log.Fatal("Erro ao realizar nova conexão com azure", err)
            return
        } else {
            fmt.Println("Sucesso ao se conectar com o azure")
        }

        u, err := url.Parse(fmt.Sprintf("https://%s.blob.core.windows.net/%s/%s", accountName, containerName, blobName))
        if err != nil {
            c.JSON(http.StatusInternalServerError, gin.H{
                "Erro ao ler URL do container": err,
            })
            log.Fatal("Erro ao ler URL do container", err)
            return
        } else {
            fmt.Println("Sucesso ao ler URL do container, eu passei por aqui")
            c.JSON(200, gin.H{
                "Sucesso ao ler URL do container": "Eu passei por aqui",
            })
        }
        blobURL := azblob.NewBlockBlobURL(*u, azblob.NewPipeline(credential, azblob.PipelineOptions{}))
        c.JSON(200, gin.H{
            "Sucesso ao ler URL do container": "Próximo passo",
        })
        log.Println("Sucesso ao ler URL do container")

        form, err := c.MultipartForm()
        if err != nil {
            c.JSON(http.StatusInternalServerError, gin.H{
                "Erro ao ler arquivo": err.Error(),
            })
            log.Println("Erro ao ler arquivo", err)
            return
        }

        files := form.File["upload"]
        if len(files) == 0 {
            c.JSON(http.StatusBadRequest, gin.H{
                "Erro ao enviar arquivo para container": "Nenhum arquivo enviado",
            })
            log.Println("Nenhum arquivo enviado", err)
            return
        }

        file := files[0]

        fmt.Println("eu passei por files", file)

        log.Println(file.Filename)

        src, err := file.Open()
        if err != nil {
            c.JSON(500, gin.H{
                "Erro ao abrir arquivo": err,
            })
            log.Fatal("Erro ao abrir arquivo", err)
            return
        } else {
            fmt.Println("Sucesso ao abrir arquivo")
            c.JSON(200, gin.H{
                "Sucesso ao abrir arquivo": "Proximo passo",
            })
        }

        options := azblob.UploadStreamToBlockBlobOptions{
            MaxBuffers: 3,
        }
        _, err = azblob.UploadStreamToBlockBlob(context.Background(), src, blobURL, options)

        if err != nil {
            fmt.Println("deu erro, mas passei por aqui")
            c.JSON(http.StatusInternalServerError, "Deu erro, mas passei aqui")
            c.JSON(http.StatusInternalServerError, gin.H{
                "Erro ao enviar arquivo para container": err.Error(),
            })
            log.Println("Erro ao enviar arquivo para container", err)
            return
        } else {
            c.JSON(http.StatusOK, gin.H{
                "message": "Arquivo enviado com sucesso!",
            })
            fmt.Println("Sucesso ao enviar arquivo")

        }
    })
    router.Run(":8080")
}

使用Postman测试时按以下步骤操作:

  • 选择POST请求方法
  • 输入API的URL地址
  • 在Body标签下选择form-data格式
  • 在Key列填写blobName,类型选择file并选中要上传的文件
  • 发送请求

收到如下错误:

上传文件至容器失败 write error: -> github.com/Azure/azure-storage-blob-go/azblob.newStorageError, C:/Users/rodri/go/pkg/mod/github.com/!azure/azure-storage-blob-go@v0.15.0/azblob/zc_storage_error.go:42
===== RESPONSE ERROR (ServiceCode=InvalidUri) =====
描述:请求的URI不代表服务器上的任何资源。
RequestId:a31b34a1-401e-000c-3aa8-6fb698000000
时间:2023-04-15T14:43:41.9699330Z, 详情:
   代码: InvalidUri
   UriPath: https://blablabla.blob.core.windows.net/teste/?blockid=mLa1s8Y9Tu6Tqw0umZ2kiwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==&comp=block&timeout=61        
   PUT https://blablabla.blob.core.windows.net/teste/?blockid=mLa1s8Y9Tu6Tqw0umZ2kiwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%3D%3D&comp=block&timeout=61
   Authorization: REDACTED
   Content-Length: [5]
   User-Agent: [Azure-Storage/0.15 (go1.20; Windows_NT)]
   X-Ms-Client-Request-Id: [5e531a97-f854-476c-49f7-407a29468e89]
   X-Ms-Date: [Sat, 15 Apr 2023 14:43:41 GMT]
   X-Ms-Version: [2020-10-02]
   --------------------------------------------------------------------------------
   响应状态: 400 The requested URI does not represent any resource on the server.      
   Content-Length: [438]
   Content-Type: [application/xml]
   Date: [Sat, 15 Apr 2023 14:43:41 GMT]
   Server: [Microsoft-HTTPAPI/2.0]
   X-Ms-Error-Code: [InvalidUri]
   X-Ms-Request-Id: [a31b34a1-401e-000c-3aa8-6fb698000000]

错误原因

从错误信息的UriPath可以看到,请求路径仅指向Azure存储容器(https://blablabla.blob.core.windows.net/teste/),缺少具体的Blob文件名,导致Azure无法识别该URI为有效的上传目标,返回InvalidUri错误。

根源是Postman配置错误:你将blobName的类型设为了File,但代码里c.PostForm("blobName")需要获取文本类型的参数,这会导致blobName为空值。空值拼接后生成的Blob URL缺少文件名,最终触发错误。

修复方案

1. 修正Postman请求配置

在form-data中配置两个独立的Key:

  • blobName:类型选择Text,填入你希望上传后Blob的文件名(例如document.pdf)
  • upload:类型选择File,选中本地要上传的文件

2. 代码优化(可选)

为避免类似空值问题,建议在代码中增加blobName的非空校验:

blobName := c.PostForm("blobName")
// 新增非空校验
if blobName == "" {
    c.JSON(http.StatusBadRequest, gin.H{
        "error": "blobName参数不能为空,请指定上传后的Blob文件名",
    })
    return
}

内容的提问来源于stack exchange,提问作者Guilherme Rodrigues

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 20:54:58