How can you read POST data from a javascript XMLHttpRequest in Golang?

Issue

Here’s the javascript function called:

function cwk_submit_form() {
   var form = document.getElementById("FORM_ID")
   var XHR = new XMLHttpRequest();


   const FD = new FormData( form );
   for (const element of FD.entries()) {
       console.log(element)
   }

   XHR.open( "POST", "http://localhost:8080/post_data" );
   XHR.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

   XHR.send( FD );
}

I left the console.log in there to mention that this does print out the correct data, meaning that the issue is seems to be in how the data is transferred.

The Golang code that receives the response is:

func post_data(w http.ResponseWriter, r *http.Request) {
    log.Println("post was called")

    r.ParseForm()
    for key, value := range r.Form {
        log.Printf("%s = %s\n", key, value)
    }
}

Nothing is printed by this for loop.

If I use an HTML Form to submit like so:

<form action="//localhost:8080/post_data" method="POST">
    <input type="text" name="field1" value="" maxLength="20"/>
        
    <input type="text" name="field2" value="" maxLength="20"/>
        
    <input type="submit" value="Sign in"/>
</form>

then the Golang code above works fine, which leads me to believe that the XMLHttpRequest format is the issue.

Solution

Your guess is right there is a problem in your js code.

For all requests, ParseForm parses the raw query from the URL and updates r.Form.

And hence, it will work when the Content-Type you send and the actual content type matches to application/x-www-form-urlencoded which happens in your HTML form case.

On the other hand, when you use FormData, it will be sent as multipart/form-data.

You need to replace your XHR.send(FD) with XHR.send(new URLSearchParams(FD)) in order to send the data in application/x-www-form-urlencoded.

Answered By – Nick

Answer Checked By – Jay B. (GoLangFix Admin)

Leave a Reply

Your email address will not be published.