Golang net / http上传大文件,未定义错误

时间:2017-06-10 16:50:47

标签: javascript file http typescript go

我在使用golang的默认net / http包上传大型文件到服务器时遇到了一个很难调试的错误。上传代码如下所示:

    uploadForm.onsubmit = () => {
        const formData = new FormData(uploadForm);
        const isPublic : boolean = (<HTMLInputElement>document.getElementById('public_switch')).checked;
        formData.append('file', (<HTMLInputElement>document.getElementById('file')).files[0]);
        formData.append('compression', (<HTMLInputElement>document.getElementById('compression')).value);
        formData.append('public', String(isPublic));
        const xhr = new XMLHttpRequest();
        xhr.open("POST", "/upload/");
        xhr.send(formData);
        xhr.onreadystatechange = function() {
            console.log(xhr.responseText);
        }
    }

我有一个用golang编写的服务器,我从以下开始:

var server = &http.Server{
    Addr:         ":" + Configuration.Port,
    ReadTimeout:  300 * time.Second,
    WriteTimeout: 300 * time.Second,
    ReadHeaderTimeout: 300 * time.Second,
    MaxHeaderBytes: 500000000}

http.HandleFunc("/upload/", uploadFile)

server.ListenAndServe()

最后,我接受并使用以下代码解析文件

func uploadFile(w http.ResponseWriter, r *http.Request) {
    //Parsing the upload arguments into the values we shall be working with
    r.ParseMultipartForm(5000000000000000)

    file, _, err := r.FormFile("file")
    //etc

现在,代码本身在&#f; r.FormFile(&#34; file&#34;)&#39;使用描述性错误消息:&#34; multipart:NextPart:EOF&#34;

是否存在某种文件限制或超时设置,我可能无法在go代码或javascript中设置?我尝试上传的文件大约为1.7GB,因此显然符合http支持的限制。

任何想法如何更好地调试此问题,而无需深入研究FormFile或捕获请求本身?代码适用于较小的文件(几个Mb&#39;)。

1 个答案:

答案 0 :(得分:0)

好的,回答我自己的问题,以防再次出现这个问题。

问题是javascript方面的问题很糟糕,我担心它与表格和文件的网页api实际上并没有真正的问题有关。

这是我提出的javascript方面的解决方案:

const uploadFile = (form_id: string) => {
    const uploadForm: HTMLFormElement = <HTMLFormElement>document.getElementById(form_id);
    document.getElementById("submit_form").addEventListener("click", function(e) {
        e.preventDefault()

        let reader: FileReader = new FileReader();
        reader.readAsArrayBuffer((<HTMLInputElement>document.getElementById('file')).files[0]);

        reader.onload = function(evt) {

            const formData = new FormData(uploadForm);
            const isPublic: boolean = (<HTMLInputElement>document.getElementById('public_switch')).checked;
            formData.append('file', (<any>evt.target).result);
            formData.append('compression', (<HTMLInputElement>document.getElementById('compression')).value);
            formData.append('public', String(isPublic));
            const xhr = new XMLHttpRequest();
            xhr.open("POST", "/upload/");
            xhr.send(formData);
            xhr.onreadystatechange = function() {
                console.log(xhr.responseText + '  \n status is: ' + xhr.statusText);
            }

        };
    });

}

非常简单,但需要花费很长时间才能找到,因为在典型的javascipt社区精神中,所有在线示例都充满了混乱。

大文件的处理应该使用FileReader对象来完成,该对象基本上是这样调用的:

 let reader = new FileReader();
        reader.readAsArrayBuffer(dom_element_with_file_input.files[0]);

然后它的使用方式与其他任何异步web api一样:

    reader.onload = function(e) {
const your_file = e.target.result
    }

变量'your_file'随后用于您想要对文件执行的任何操作。在我的情况下,它附加了表格数据,这样做:

        reader.onload = function(e) {
    const your_file = e.target.result
const formData = new FormData(dom_element_of_type_form);
formData.append('my_file', your_file);
formData.append('other_stuff', 'a string with metadata');
        }

我要离开这个作为一个例子,因为我实际上找不到任何这样的帖子,带有一个明确的Reader API文件示例,期望那些杂乱无章的数百行代码。我几乎跟随T的例子就是这里的例子:

https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications。但我使用'readAsArrayBuffer'来代替速度。

最后一个注意事项是,阅读器API似乎非常慢并消耗了大量的资源,这意味着对于任意文件大小的浏览器可能只是崩溃,我遇到了这个问题,我仍然无法修复它,所以我愿意接受建议,如果我找到了解决浏览器崩溃的问题(或者至少是一种优雅地处理它们的方法)我会更新问题并将其标记为答案,同时如果有人发现我的答案重复或者一种修复浏览器崩溃的方法请告诉我。