在一个 HTTP 请求中发送文件和参数(通过 JSON)

Send a File as well as parameters (through JSON) inside one HTTP request

我正在使用 Go 创建一个服务器,它允许客户端上传文件,然后使用服务器函数来解析文件。目前,我正在使用两个单独的请求: 1)第一个请求发送用户上传的文件 2)第二个请求向服务器发送服务器解析文件所需的参数。

但是,我意识到由于程序的性质,如果多个用户同时尝试使用服务器,可能会出现并发问题。我的解决方案是使用互斥锁。但是,我正在接收文件、发送响应,然后接收参数,似乎 Go 无法在互斥体锁定时发回响应。我正在考虑通过在一个 HTTP 请求中同时发送文件和参数来解决这个问题。有没有办法做到这一点?谢谢

示例代码(仅相关部分):

从客户端发送文件的代码:

handleUpload() {
        const data = new FormData()

        for(var x = 0; x < this.state.selectedFile.length; x++) {
            data.append('myFile', this.state.selectedFile[x])
        }

        var self = this;
        let url = *the appropriate url*
        axios.post(url, data, {})
        .then(res => {
            //other logic
            self.handleParser();
        })
}

handleParser() 代码:

    handleNessusParser(){

        let parserParameter = {
        SourcePath : location,
        ProjectName : this.state.projectName
        }

        // fetch the the response from the server
        let self = this;
        let url = *url*
        fetch(url, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(parserParameter),

        }).then( (response) => {

        if(response.status === 200) {

           //success logic
        }


        }).catch (function (error) {

        console.log("error: ", error);

        });     
    }

这个问题并不是关于 Go 或 reactjs 或任何特定的软件库。

要解决您的问题,您首先需要了解 HTTP POST 的工作原理, 因此,我邀请您先阅读 this intro on MDN.
简而言之:

  • 有多种方法可以对 POST 请求中发送的数据进行编码。
  • 接收方处理此数据的方式取决于发送方对其进行编码的方式。
  • 发件人必须在其请求中传达编码 — 通常通过 Content-Type header 字段。

我不会详细介绍可能的编码 - 参考介绍 material 涵盖了它们,您应该对它们进行自己的研究,但为了回顾一下那里写的内容,这里有一些观点.

回到 80 年代和 90 年代,网络是 "static",可怕的 JavaScript-heavy "web apps" 时代还没有到来。 "Static" 意味着您不能 运行 客户端浏览器中的任何代码,并且必须根据普通 HTML.

对与服务器的任何通信进行编码

一个 HTML 文档可以有两种方式让客户端呈现它以将某些内容发送回服务器:a) 嵌入一个包含查询参数的 URL;这将使客户端使用发送到服务器的这些参数执行 GET 请求; b) 嵌入一个 HTML "form",当 "submitted" 时,将导致使用从填写的表单中获取的数据执行相当复杂的 POST 请求。

后一种方法是利用浏览器的能力来执行相当复杂的数据处理——例如将用户在特定表单的控件中选择的文件压缩,对其进行适当编码并将其与其他表格的数据。
有两种编码表单数据的方法,它们都包含在链接的文章中,请阅读它们。

理解这种 "static web with forms" 方法的关键是它的工作原理是这样的:服务器发送一个 HTML 包含网络表单的文档,浏览器呈现文档,用户填写进入并点击浏览器呈现的 "submit" 按钮;浏览器从表单控件收集数据,对于 "file" 类型的条目,它读取并编码这些文件的内容,最后执行 HTTP POST 请求,并将这些内容编码为 URL由表格指定。服务器通常会响应另一个 HTML 文档等。

好的,所以"web 2.0"来了,发明了"XHR"(XMLHttpRequest)。它的名字中有 "XML",因为那时候 XML 被一些人视为可以解决任何计算问题的圣杯(当然,它没有做到)。发明那个东西是为了能够发送几乎任意的数据有效载荷;至少支持 XML 和 JSON 编码。

要理解的关键是,这种与服务器通信的方式与原始方式完全并行,它们唯一的共同点是它们都使用 HTTP POST 请求。

到现在你应该看到了全貌:现代 JS 库允许你构建和执行任何类型的请求:它们允许你创建一个 "web form" 风格的请求或创建一个 JS object,并将其序列化为 JSON,并在 HTTP POST 请求中发送结果。

如您所见,any 方法允许您将包含多个不同数据片段的结构化数据传递给服务器,处理这一切的方式是一个协议问题在服务器和客户端之间,即 API 约定,如果需要的话。

各种方法之间的区别在于 web-form-style 方法会为您编码文件的内容,而如果您选择以 JSON [=83] 的方式发送文件=],你需要自己编码——比如说,使用 base64 编码。

组合方法也是可能的。
例如,您可以直接将文件的二进制数据作为 POST 请求的 body 发送,并通过将它们编码为 query-parameters 的 URL 来随请求一起提交一组参数=].同样,这取决于客户端和服务器之间关于后者如何对要发送的数据进行编码以及前者如何对其进行解码的协议。


All-in-all,我建议暂停一下,了解一下我上面概述的内容,然后再尝试解决问题,但这一次 — 对如何解决问题有相当完整的了解这些东西在引擎盖下工作,以及你打算如何使用它。