Using fetch instead of form

Good ol’ form. I have been using it to make POST requests for all the applications that I have built until now. Safe to say, those weren’t “real world production” applications because using form is not a good way to make requests.

The main problem I faced with it was form resubmission. Whenever someone refreshed the endpoint, it would send the same data back to the backend. I tried to send GET request on refresh but I didn’t work.

Quick reminder on forms

Let’s do a quick refresher on forms.

For making any kind of request:

<form method="POST" action="/test">
    <input type="text">
    <button type="submit">Submit</button>

Then we can handle it on backend, I will use Flask as I am quite familiar with it:

@app.route('/test', methods=['POST'])
def test():
    test = request.form.get('test')

Simple and easy to do.

However, as I said previously, there’s a better way. Given, we have to use JS, which I tried so hard to avoid but there seems to be no other option.

Using fetch

Instead of using html forms, we can use fetch which is a modern version of jQuery. Let’s see how to use it:

First, let’s make a simple html page:

        <input type="text" id="url">
        <button type="submit">Submit</button>

Now, we can create a fetch request which will be sent to the backend:

var instruction = document.getElementById('url')
fetch('/test', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
    body: JSON.stringify({
        instruction: instruction,

First we define our endpoint which is test. After that, we specify the method type, content-type and body data.

Now, let’s handle the request with Flask

@app.route('/test', methods=['POST'])
def test():
    if request.method == POST:
        data = request.json

        status_code = 200
        response = make_response('', status_code)
        return response
    return data

I am simply returning 200 status code if the request was successful. We can now handle that response in our fetch request:

.then(response => {
    if (response.ok) {
        console.log("response ok")

        window.location.href = '/test';
    } else {
        console.error('Request failed with status:', response.status);
.catch(error => console.error('Error:', error));

After getting 200 response code, we redirect it to /test and that will return the data.

That’s it for this one. Keep experimenting!