httpxmlhttprequesthttp-posthttp-post-vars

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


I am creating a server using Go that allows the client to upload a file and then use a server function to parse the file. Currently, I am using two separate requests: 1) First request sends the file the user has uploaded 2) Second request sends the parameters to the server that the server needs to parse the file.

However, I have realised that due to the nature of the program, there can be concurrency problem if multiple users try to use the server at the same time. My solution to that was using mutex locks. However, I am receiving the file, sending a response, and then receiving the parameters and it seems that Go cannot send a response back when the mutex is locked. I am thinking about solving this problem by sending both the file and the parameters in one single HTTP request. Is there a way to do that? Thanks

Sample code (only relevant parts):

Code to send file from client:

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();
        })
}

Code for 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);

        });     
    }

Solution

  • The question is not really about Go or reactjs or any particular software library.

    To solve your problem you'd first need to understand how HTTP POST works, hence I invite you to first read this intro on MDN.
    In short:

    I won't go into the details of possible encodings — the referenced introductory material covers them, and you should do your own research on them, but to maybe recap what's written there, here is some perspective.

    Back in the 80s and 90s the web was "static" and the dreaded era of JavaScript-heavy "web apps" did not yet come. "Static" means you could not run any code in the client's browser, and had to encode any communication with the server in terms of plain HTML.

    An HTML document could have two ways to make the client rendering it to send something back to the server: a) embed an URL which would include query parameters; this would make the client to perform a GET request with these parameters sent to the server; b) embed an HTML "form" which, when "submitted", would result in performing a rather more complex POST request with the data taken from the filled in form.

    The latter approach was the way to leverage the browser's ability to perform reasonably complex data processing — such as slurpling a file selected by the user in a specific form's control, encoding it appropriately and sending it to the server along with the other form's data.
    There were two ways to encode the form's data, and they are both covered by the linked article, please read about them.

    The crucial thing to understand about this "static web with forms" approach is that it worked like this: the server sends an HTML document containing a web form, the browser renders the document, the user fills the form in and clicks the "submit" button rendered by the browser; the browser collects the data from the form's controls, for entries of type "file" it reads and encodes the contents of those files and finally performs an HTTP POST request with this stuff encoded to the URL specified by the form. The server would typically respond with another HTML document and so on.

    OK, so here came "web 2.0", and an "XHR" (XMLHttpRequest) was invented. It has "XML" in its name because that was the time when XML was perceived by some as a holy grail which would solve any computing problem (which it, of course, failed to do). That thing was invended to be able to send almost arbitrary data payloads; XML and JSON encoding were supported at least.

    The crucial thing to understand is that this way to communicate with the server is completely parallel to the original one, and the only thing they share is that they both use HTTP POST requests.

    By now you should possibly see the whole picture: contemporary JS libs allow you to contruct and perform any sort of request: they allow you to create a "web form"-style request or to create a JS object, and serialise it to JSON, and send the result in an HTTP POST request.

    As you can see, any approach allows you to pass structured data containing multiple distinct pieces of data to the server, and the way to handle this all is a matter of agreement between the server and the client, that is, the API convention, if you want.

    The difference between various approaches is that the web-form-style approach would take care of encoding the contents of the file for you, while if you opt to send your file in a JSON object, you'll need to encode it yourself — say, using base64 encoding.

    Combined approaches are possible, too.
    For instance, you can directly send binary data of a file as a POST request's body, and submit a set of parameters along with the request by encoding them as query-parameters of the URL. Again, it's up to the agreement between the client and the server about how the latter encodes the data to be sent and the former decodes them.


    All-in-all, I'd recommend to take a pause and educate yourself on the stuff I have outlined above, and then have another stab at solving the problem, but this time — with reasonably complete understanding about how the stuff works under the hood, and how you intend to wield it.