Ajax上传文件到内容类型为Multipart的GoLang服务器

时间:2014-08-25 20:17:51

标签: javascript html ajax go multipart

我正在尝试使用多部分表单将音频文件上传到Golang服务器。但是,Go返回错误:

multipart: NextPart: bufio: buffer full

我相信这表明我的Javascript请求中存在多部分格式的内容。这是我的Javascript:

function UploadFile(file) {
    var xhr = new XMLHttpRequest();


    if (file.type == "audio/mpeg" && file.size <= $id("MAX_FILE_SIZE").value) {
        // start upload
        var boundary = '---------------------------' + Math.floor(Math.random()*32768) + Math.floor(Math.random()*32768) + Math.floor(Math.random()*32768);

        xhr.open("POST", $id("upload").action, true);
        xhr.setRequestHeader("Content-Type", "multipart/form-data; boundary=" + boundary);
        xhr.setRequestHeader("X_FILENAME", file.name);
        xhr.send(file);
    }
}

这是我的Golang服务器处理程序:

func FileHandler(w http.ResponseWriter, r *http.Request) {
    var (
        status int
        err    error
    )
    defer func() {
        if nil != err {
            http.Error(w, err.Error(), status)
        }
    }()
    // parse request with maximum memory of _24Kilobits
    const _24K = (1 << 20) * 24
    if err = r.ParseMultipartForm(_24K); nil != err {
        fmt.Println(err)
        status = http.StatusInternalServerError
        return
    }
    for _, fheaders := range r.MultipartForm.File {
        for _, hdr := range fheaders {
            // open uploaded
            var infile multipart.File
            if infile, err = hdr.Open(); nil != err {
                status = http.StatusInternalServerError
                return
            }
            // open destination
            var outfile *os.File
            if outfile, err = os.Create("./uploaded/" + hdr.Filename); nil != err {
                status = http.StatusInternalServerError
                return
            }
            // 32K buffer copy
            var written int64
            if written, err = io.Copy(outfile, infile); nil != err {
                status = http.StatusInternalServerError
                return
            }
        w.Write([]byte("uploaded file:" + hdr.Filename + ";length:" + strconv.Itoa(int(written))))
        }
    }
}

如果有人有任何想法我为什么会收到这个错误,我会非常感激。

2 个答案:

答案 0 :(得分:2)

经过与Ajax请求的漫长而艰苦的斗争,我得到了它发送正确的信息。这是我使用的代码:

var xhr = new XMLHttpRequest(),
    boundary=Math.random().toString().substr(2);

var formdata = new FormData();
formdata.append("file", file);

xhr.open("POST", $id("upload").action, true);
//xhr.setRequestHeader("content-type", "multipart/form-data; charset=utf-8; boundary=" + boundary);
xhr.send(formdata);

请注意标题已不再使用,我发现您可以比其他方法更轻松地将数据附加到formdata:How to send multipart/form-data form content by ajax (no jquery)?

答案 1 :(得分:0)

不确定这个答案是否适合您,但我能够在客户端使用FiniteBits通过ajax上传文件,并在服务器上使用以下一小段Go代码:

import UIKit

class ViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate{


    @IBOutlet weak var see: UITextField!


    var pick = ["1", "2", "3", "4"]
    var picker = UIPickerView()
    var picker2 = UIPickerView()


    @IBOutlet weak var see2: UITextField!


    var viewone = ["1", "2", "3"]
    var viewtwo = ["1", "2", "3"]


    override func viewDidLoad() {
        super.viewDidLoad()
        picker.delegate = self
        picker.dataSource = self
        picker2.delegate = self
        picker2.dataSource = self
        see.inputView = picker
        see2.inputView = picker2
        picker.tag = 1
        picker2.tag = 2
    }

    func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
        return 1
    }

    func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        if pickerView.tag == 1 {
            return pick.count
        }else if pickerView.tag == 2{
            if see.text == "1"{
                return viewone.count
            }else if see.text == "2"{
                return viewtwo.count
            }else{
                return 1
            }
        }else{
            return 1
        }
    }

    func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        see.text = pick[row]

    }

    func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        if pickerView.tag == 1{
            return "\(pick[row])"
        }else if pickerView.tag == 2{
            if see.text == "1"{
                return "\(viewone[row])"
            }else if see.text == "2"{
                return "\(viewtwo[row])"
            }else{
                return nil
            }
        }else{
            return nil
        }
    }

此处form-datafile, handler, err := r.FormFile("img") // img is the key of the form-data if err != nil { fmt.Println(err) return } defer file.Close() fmt.Println("File is good") fmt.Println(handler.Filename) fmt.Println() fmt.Println(handler.Header) f, err := os.OpenFile(handler.Filename, os.O_WRONLY|os.O_CREATE, 0666) if err != nil { fmt.Println(err) return } defer f.Close() io.Copy(f, file) 。附:这只是将文件存储在同一文件夹中,并且不执行任何安全检查。