基于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
相关产品推荐
相关产品推荐

