Golang中如何获取服务器接收文件的完整路径

Golang中如何获取服务器接收文件的完整路径 当客户端向服务器发送此文件时: “D:\folder\nameFile.txt”

服务器能获取到该路径吗?还是我应该在表单中插入一个额外的字段,将其作为字符串显式发送?

2 回复

不,你无法获取那个信息。浏览器是故意不发送那个信息的。反正你也不能使用那个信息。D:\folder\nameFile.txt 在你的服务器上可能并不存在(而且在我的服务器上肯定不存在,因为我拒绝运行 Windows 系统)。

// 代码部分保持原样,此处仅为示例占位符

更多关于Golang中如何获取服务器接收文件的完整路径的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go语言中,服务器无法直接获取客户端文件在发送前的完整本地路径。这是出于安全考虑,浏览器不会在文件上传请求中包含原始路径信息。你需要通过表单的额外字段显式发送这个路径。

下面是一个完整的示例,展示如何通过表单同时上传文件和文件路径:

客户端HTML表单示例:

<form action="/upload" method="post" enctype="multipart/form-data">
    <input type="file" name="file">
    <input type="hidden" name="filepath" id="filepath">
    <input type="submit" value="上传">
</form>

<script>
document.querySelector('input[type="file"]').addEventListener('change', function(e) {
    document.getElementById('filepath').value = this.value;
});
</script>

服务器端Go代码示例:

package main

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

func uploadHandler(w http.ResponseWriter, r *http.Request) {
    // 解析multipart表单,限制上传大小为10MB
    err := r.ParseMultipartForm(10 << 20)
    if err != nil {
        http.Error(w, "无法解析表单", http.StatusBadRequest)
        return
    }

    // 获取上传的文件
    file, handler, err := r.FormFile("file")
    if err != nil {
        http.Error(w, "获取文件失败", http.StatusBadRequest)
        return
    }
    defer file.Close()

    // 获取客户端发送的原始文件路径
    originalPath := r.FormValue("filepath")
    fmt.Printf("客户端原始路径: %s\n", originalPath)
    fmt.Printf("上传文件名: %s\n", handler.Filename)

    // 在服务器端创建保存文件的路径
    serverPath := filepath.Join("uploads", handler.Filename)
    
    // 创建目标文件
    dst, err := os.Create(serverPath)
    if err != nil {
        http.Error(w, "创建文件失败", http.StatusInternalServerError)
        return
    }
    defer dst.Close()

    // 复制文件内容
    _, err = io.Copy(dst, file)
    if err != nil {
        http.Error(w, "保存文件失败", http.StatusInternalServerError)
        return
    }

    fmt.Fprintf(w, "文件上传成功\n")
    fmt.Fprintf(w, "客户端路径: %s\n", originalPath)
    fmt.Fprintf(w, "服务器保存路径: %s\n", serverPath)
}

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

使用curl测试的示例:

curl -F "file=@/home/user/document.txt" \
     -F "filepath=/home/user/document.txt" \
     http://localhost:8080/upload

使用标准库的multipart.Writer示例:

// 客户端Go代码示例
func uploadFile(clientFilePath, serverURL string) error {
    file, err := os.Open(clientFilePath)
    if err != nil {
        return err
    }
    defer file.Close()

    body := &bytes.Buffer{}
    writer := multipart.NewWriter(body)
    
    // 添加文件
    part, err := writer.CreateFormFile("file", filepath.Base(clientFilePath))
    if err != nil {
        return err
    }
    io.Copy(part, file)
    
    // 添加文件路径字段
    writer.WriteField("filepath", clientFilePath)
    writer.Close()

    req, err := http.NewRequest("POST", serverURL, body)
    if err != nil {
        return err
    }
    req.Header.Set("Content-Type", writer.FormDataContentType())

    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        return err
    }
    defer resp.Body.Close()

    return nil
}

在这个实现中,服务器通过r.FormValue("filepath")获取客户端显式发送的原始文件路径,而通过handler.Filename只能获取到文件名(不包含完整路径)。这是标准的文件上传实现方式,确保了安全性和跨浏览器兼容性。

回到顶部