multipart/form-data编码通常用于实现文件上传功能,这种功能需要用到file类型的input标签。代码清单4-5给出的就是之前展示过的客户端表单在实现了文件上传功能之后的样子,其中以加粗方式呈现的是新增或者经过修改的代码。

<html>  
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>Go Web Programming< /title>
    </head>
    <body>
        <form action="http://localhost:8080/process?hello=world&thread=123"  
            method="post" enctype="multipart/form-data">
            <input type="text" name="hello" value="sau sheong"/>
            <input type="text" name="post" value="456"/>      
            <input type="file" name="uploaded">      
            <input type="submit">    
        </form>
    </body>
</html>

为了能够接收表单上传的文件,处理器函数也需要做相应的修改,具体见代码清单4-6。

代码清单4-6 通过MultipartForm字段接收用户上传的文件

package main

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

func process(w http.ResponseWriter, r *http.Request) {
    r.ParseMultipartForm(1024)
    fileHeader := r.MultipartForm.File["uploaded"][0]
    file, err := fileHeader.Open()
    if err == nil {
        data, err := ioutil.ReadAll(file)
        if err == nil {
            fmt.Fprintln(w, string(data))
        }
    }
}

func main() {
    server := http.Server {
        Addr: "127.0.0.1:8080",
    }

    http.HandleFunc("/process",process)
    server.ListenAndServe()
}

正如之前所说,服务器在处理文件上传时首先要做的就是执行ParseMultipartForm方法,接着从MultipartForm字段的File字段里面取出文件头FileHeader,然后通过调用文件头的Open方法来打开文件。在此之后,服务器会将文件的内容读取到一个字节数组中,并将这个字节数组的内容打印出来。现在,如果我们向服务器上传一个纯文本文件,那么服务器将把这个文件的内容打印在浏览器上。

FormValue方法和PostFormValue方法类似,net/http库也提供了一个FormFile方法,它可以快速地获取被上传的文件:FormFile方法在被调用时将返回给定键的第一个值,因此它在客户端只上传了一个文件的情况下,使用起来会非常方便。代码清单4-7展示了一个使用FormFile方法的例子。

代码清单4-7 使用FormFile方法获取被上传的文件

func process(w http.ResponseWriter, r *http.Request) {    
    file, _, err := r.FormFile("uploaded")    
    if err == nil {        
        data, err := ioutil.ReadAll(file)        
        if err == nil {            
            fmt.Fprintln(w, string(data))        
        }    
    }
}

正如代码所示,FormFile方法将同时返回文件和文件头作为结果。用户在使用FormFile方法时,将不再需要手动调用ParseMultipartForm方法,只需要对返回的文件进行处理即可。

results matching ""

    No results matching ""