Golang从接口端点获取图片表单数据时遇到问题

Golang从接口端点获取图片表单数据时遇到问题 我使用Go作为后端,uikit(CSS框架)作为前端,尝试上传文件:https://codepen.io/kent_iyo/pen/VwLbvmg。除非我想扩展源代码,否则我的选择有限,但以下是提交图片后的ajax调用:https://github.com/uikit/uikit/blob/a7ad0746cd078eb973b27af8bd8a4f9eb58709c8/src/js/components/upload.js

js

const data = new FormData();
files.forEach(file => data.append(this.name, file));

html

<div class="js-upload uk-placeholder uk-text-center">
    <span uk-icon="icon: cloud-upload"></span>
    <span class="uk-text-middle uk-margin-small-left">Attach files by dropping them here or</span>
    <div uk-form-custom>
         <input name="this_is_the_file_i_want" type="file" accept="image/png, image/jpeg" multiple>
          <span class="uk-link">selecting one</span>
    </div>
</div>

调用后(没有错误),我尝试使用 ParseMultipartFormr.FormValue 访问数据,但似乎无法获取到任何内容。

有人能指点我如何访问这些文件吗?


更多关于Golang从接口端点获取图片表单数据时遇到问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang从接口端点获取图片表单数据时遇到问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go中处理文件上传时,你需要正确解析multipart/form-data请求。以下是处理UIkit上传组件的示例代码:

package main

import (
    "fmt"
    "io"
    "net/http"
    "os"
)

func uploadHandler(w http.ResponseWriter, r *http.Request) {
    // 设置最大文件大小(例如10MB)
    r.ParseMultipartForm(10 << 20)
    
    // 获取文件头
    file, handler, err := r.FormFile("this_is_the_file_i_want")
    if err != nil {
        fmt.Println("Error retrieving the file:", err)
        http.Error(w, "Error retrieving file", http.StatusBadRequest)
        return
    }
    defer file.Close()
    
    // 打印文件信息
    fmt.Printf("Uploaded File: %+v\n", handler.Filename)
    fmt.Printf("File Size: %+v\n", handler.Size)
    fmt.Printf("MIME Header: %+v\n", handler.Header)
    
    // 创建目标文件
    dst, err := os.Create("/tmp/" + handler.Filename)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    defer dst.Close()
    
    // 复制文件内容
    if _, err := io.Copy(dst, file); err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    
    fmt.Fprintf(w, "Successfully uploaded file")
}

// 处理多个文件上传
func uploadMultipleHandler(w http.ResponseWriter, r *http.Request) {
    // 设置最大文件大小
    r.ParseMultipartForm(10 << 20)
    
    // 获取multipart reader
    reader, err := r.MultipartReader()
    if err != nil {
        http.Error(w, err.Error(), http.StatusBadRequest)
        return
    }
    
    // 遍历所有part
    for {
        part, err := reader.NextPart()
        if err == io.EOF {
            break
        }
        if err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }
        
        // 检查是否是文件字段
        if part.FileName() != "" {
            fmt.Printf("Fieldname: %s, Filename: %s\n", part.FormName(), part.FileName())
            
            // 保存文件
            dst, err := os.Create("/tmp/" + part.FileName())
            if err != nil {
                http.Error(w, err.Error(), http.StatusInternalServerError)
                return
            }
            
            if _, err := io.Copy(dst, part); err != nil {
                dst.Close()
                http.Error(w, err.Error(), http.StatusInternalServerError)
                return
            }
            dst.Close()
        }
    }
    
    fmt.Fprintf(w, "Successfully uploaded files")
}

func main() {
    http.HandleFunc("/upload", uploadHandler)
    http.HandleFunc("/upload-multiple", uploadMultipleHandler)
    http.ListenAndServe(":8080", nil)
}

如果你的前端使用multiple属性上传多个文件,可以使用这个替代方案:

func uploadMultipleFiles(w http.ResponseWriter, r *http.Request) {
    // 解析multipart表单
    err := r.ParseMultipartForm(10 << 20) // 10MB
    if err != nil {
        http.Error(w, err.Error(), http.StatusBadRequest)
        return
    }
    
    // 获取所有文件
    files := r.MultipartForm.File["this_is_the_file_i_want"]
    
    for _, fileHeader := range files {
        // 打开文件
        file, err := fileHeader.Open()
        if err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }
        defer file.Close()
        
        // 创建目标文件
        dst, err := os.Create("/tmp/" + fileHeader.Filename)
        if err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }
        defer dst.Close()
        
        // 复制文件内容
        if _, err := io.Copy(dst, file); err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }
    }
    
    fmt.Fprintf(w, "Successfully uploaded %d files", len(files))
}

调试时可以使用这个函数查看所有接收到的数据:

func debugUpload(w http.ResponseWriter, r *http.Request) {
    // 打印所有表单字段
    r.ParseMultipartForm(10 << 20)
    
    fmt.Println("Form values:")
    for k, v := range r.Form {
        fmt.Printf("%s: %v\n", k, v)
    }
    
    fmt.Println("\nMultipart form files:")
    for k, v := range r.MultipartForm.File {
        fmt.Printf("%s: %v files\n", k, len(v))
        for _, f := range v {
            fmt.Printf("  - %s (size: %d)\n", f.Filename, f.Size)
        }
    }
    
    fmt.Println("\nPost form values:")
    for k, v := range r.PostForm {
        fmt.Printf("%s: %v\n", k, v)
    }
}

确保你的HTML表单设置了正确的enctype:

<form action="/upload" method="POST" enctype="multipart/form-data">
    <!-- 你的文件输入字段 -->
</form>
回到顶部