文件上传

0.首先肯定是用http 的post

post 的 Content-Type 可以有很多。1 2

Content-Typevaluebody字符处理用途
application/x-www-from-urlencodedkey1=value1&key2=value2空格转换为 “+”+url编码一般的post多是用这个
binary/octet-stream二进制直接传送二进制传单个文件
multipart/form-data具体见下图会有分隔符+二进制传多个文件
text/plain?raw任意文本空格转换为 “+”json数据

这里写图片描述

似乎比较通用的上传文件的方式是用xhr(XMLHttpRequest) 3
下面把我搜到的都列一下。

1.binary/octet-stream

https://my.oschina.net/zhizhisoft/blog/1815323

2.multipart/form-data

精简版代码(包括前端和后端):
https://stackoverflow.com/questions/19267336/golang-http-handle-big-file-upload

javascript

主要用:XMLHttpRequest+form-data

js: https://www.cnblogs.com/007sx/p/7520529.html

另一个版本:4

var files = document.getElementById('pic').files; //files是文件选择框选择的文件对象数组  

if(files.length == 0) return;   

var form = new FormData(),   
    url = 'http://.......', //服务器上传地址  
    file = files[0];  
form.append('file', file);  

var xhr = new XMLHttpRequest();  
xhr.open("post", url, true);  

//上传进度事件  
xhr.upload.addEventListener("progress", function(result) {  
    if (result.lengthComputable) {  
        //上传进度  
        var percent = (result.loaded / result.total * 100).toFixed(2);   
    }  
}, false);  

xhr.addEventListener("readystatechange", function() {  
    var result = xhr;  
    if (result.status != 200) { //error  
        console.log('上传失败', result.status, result.statusText, result.response);  
    }   
    else if (result.readyState == 4) { //finished  
        console.log('上传成功', result);  
    }  
});  
xhr.send(form); //开始上传  
go

go(buffer io.copy):5

func ReceiveFile(w http.ResponseWriter, r *http.Request) {
    var Buf bytes.Buffer
    // in your case file would be fileupload
    file, header, err := r.FormFile("file")
    if err != nil {
        panic(err)
    }
    defer file.Close()
    name := strings.Split(header.Filename, ".")
    fmt.Printf("File name %s\n", name[0])
    // Copy the file data to my buffer
    io.Copy(&Buf, file)
    // do something with the contents...
    // I normally have a struct defined and unmarshal into a struct, but this will
    // work as an example
    contents := Buf.String()
    fmt.Println(contents)
    // I reset the buffer in case I want to use it again
    // reduces memory allocations in more intense projects
    Buf.Reset()
    // do something else
    // etc write header
    return
}

另外一个版本(file & iocopy & ParseMultipartForm):6 7

http.HandleFunc("/upload", upload)

// upload logic
func upload(w http.ResponseWriter, r *http.Request) {
       fmt.Println("method:", r.Method)
       if r.Method == "GET" {
           crutime := time.Now().Unix()
           h := md5.New()
           io.WriteString(h, strconv.FormatInt(crutime, 10))
           token := fmt.Sprintf("%x", h.Sum(nil))

           t, _ := template.ParseFiles("upload.gtpl")
           t.Execute(w, token)
       } else {
           r.ParseMultipartForm(32 << 20)
           file, handler, err := r.FormFile("uploadfile")
           if err != nil {
               fmt.Println(err)
               return
           }
           defer file.Close()
           fmt.Fprintf(w, "%v", handler.Header)
           f, err := os.OpenFile("./test/"+handler.Filename, os.O_WRONLY|os.O_CREATE, 0666)
           if err != nil {
               fmt.Println(err)
               return
           }
           defer f.Close()
           io.Copy(f, file)
       }
}

注意:r.ParseMultipartForm(32 << 20) ,似乎是设置读文件的缓冲区的大小为1M?超过的话写入临时文件?
一个alternative 是用 r.MultipartReader() 8传说是会以stream 方式处理:9

_, err := r.MultipartReader()
if err != nil {
    println(err)
    return
}

multiPart.Reader的使用 10
(也可以参考官方的单元测试11)

func handle(w http.ResponseWriter, req *http.Request) {
    partReader := multipart.NewReader(req.Body, boundary)
    buf := make([]byte, 256)
    for {
        part, err := partReader.NextPart()
        if err == io.EOF {
            break
        }
        var n int
        for {
            n, err = part.Read(buf)
            if err == io.EOF {
                break
            }
            fmt.Printf(string(buf[:n]))
        }
        fmt.Printf(string(buf[:n]))
    }
}
js md5 计算

https://blog.csdn.net/u012743824/article/details/78927917

js 支持拖拽

https://blog.csdn.net/u012743824/article/details/79021670

Range的

在搜索相关内容时,可能会发现http range这个,这个是用来做下载文件的断断续传的。

https://www.cnblogs.com/findumars/p/5745345.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值