2

I'm trying to create a http post request via JavaScript. However when I click submit the page refreshes and the url is changed.

I return false on the onsubmit attribute. So it should not be "submitting" in that sense.

Also my server was not hit by the XHR request.

Before:

enter image description here

After:

enter image description here

Code:

<form onsubmit="return test(this)">
    url:<br>
    <input type="text" id="url" name="url"><br>
    <input type="submit" value="Submit">
</form>

<script>
    function test(form) {
        var xhr = new XMLHttpRequest();

        xhr.setRequestHeader('Content-Type', 'application/json; charset=utf-8');

        xhr.open('POST', '127.0.0.1:3000/test', true);
        xhr.send(JSON.stringify({
            url: form.url.value
        }));

        xhr.onloadend = function() {
            // done
        };

        return false;
    }
</script>

I can't see when it isn't working?

basickarl
  • 37,187
  • 64
  • 214
  • 335
  • 1
    @squint I return "false" on the "onsubmit" attribute. So it should not be "submitting" in that sense. – basickarl Aug 17 '16 at 13:42
  • onsubmit attribute is showing some function and you have some other function definition. – Rajaprabhu Aravindasamy Aug 17 '16 at 13:43
  • @RajaprabhuAravindasamy Old code, I copied and pasted correctly now :) – basickarl Aug 17 '16 at 13:43
  • Karl, give the actual description of the issue in your question so we don't have to interpret your code in its absence. –  Aug 17 '16 at 13:43
  • @squint It's pretty clear; why is the page refreshing and changing my url and is not sending the request to the server? As stated the form *should not be submitting* due to the return false. – basickarl Aug 17 '16 at 13:45
  • [This deleted answer](http://stackoverflow.com/a/38998505/1106925) *does* solve the problem being asked about, since it is resilient against unrelated errors thrown after its call. Irrespective of the XHR error, it's arguably a better approach for that very reason. The answer was to pass `event` to the function, define a parameter to receive it, and call `event.preventDefault()` at the *top* of the function. –  Aug 17 '16 at 13:52
  • @squint It doesn't fix the answer because it's still not hitting the server. I just needed to switch positions of the setRequestHeader with open. – basickarl Aug 17 '16 at 14:02
  • @KarlMorrison: The problem you've described in your question is about the form submission not being prevented. That answer provides a better solution to handle this aspect. If your XHR isn't doing what you want, that needs to be fixed, irrespective of its impact on the form or anything else. –  Aug 17 '16 at 14:05
  • @squint "Also my server was not hit." – basickarl Aug 17 '16 at 14:07
  • Summary... you resist advice to provide clear information in your description, and now you're resisting information from another user who provided an arguably *better* way to do what was the *primary* topic of your conversation. I have a feeling that the true issue you're experiencing goes much deeper. –  Aug 17 '16 at 14:17

3 Answers3

1

Open the Console in your browser's developer tools. Read the error message

VM125:5 Uncaught InvalidStateError: Failed to execute 'setRequestHeader' on 'XMLHttpRequest': The object's state must be OPENED.

Since it throws an exception, it never reaches return false

Move xhr.setRequestHeader('Content-Type', 'application/json; charset=utf-8'); so it appears after xhr.open('POST', '127.0.0.1:3000/test', true);

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • Knew it was something simple! The page refreshed so quickly that I didn't see the error message, derp! – basickarl Aug 17 '16 at 14:00
  • 1
    @KarlMorrison — There's a "Preserve log" option which stops the error messages being wiped on page load. – Quentin Aug 17 '16 at 14:05
0

if you place an input of type submit inside form tag it will reload. otherwise change it to a button and run the function on button click

<form>
    url:<br>
    <input type="text" id="url" name="url"><br>
    <button>Submit</button>
</form>
  • A ` – Quentin Aug 17 '16 at 13:47
0

since you want always have false in the onsubmit attribute, you could improve the code like this:

<form onsubmit="test(this); return false;">

with this change in place, it's also semantically better to return true when everything went fine inside your xhr request. (if you want to use the function to send data in another place also.)

so your javascript becomes:

function test(form) {
    try {
        var xhr = new XMLHttpRequest();

        xhr.open('POST', '127.0.0.1:3000/test', true);
        xhr.setRequestHeader('Content-Type', 'application/json; charset=utf-8');
        xhr.send(JSON.stringify({
           url: form.url.value
        }));

        xhr.onloadend = function() {
            // done
        };
    }catch(err){
        return false;
    }

    return true;
}
Raphael Müller
  • 2,180
  • 2
  • 15
  • 20
  • actually, it's a little bit paradox to return something, because you use asynchronous functions. so what does the return value reflect? a successful submission or only that there were no errors? – Raphael Müller Aug 17 '16 at 14:05
  • I actually just want the form submit to invoke a function and do nothing else :) I re-read the answer and understand better now, smart thinking! – basickarl Aug 17 '16 at 14:06
  • 1
    Making the modification you describe doesn't help, since the exception would still abort the JavaScript and form submission would occur normally. – Quentin Aug 17 '16 at 14:07
  • As far as semantics go, it is a test that will return false if the left hand side is true, and return the left hand side (false) otherwise. So it is a really confusing test that adds nothing. If "always returning false" is the goal, then the way to express that at that level would be `onsubmit="test(this); return false;"` – Quentin Aug 17 '16 at 14:08
  • @Quentin True, I just doubled checked it and it indeed does not work. However I did set `onsubmit="test(this‌​); return false;"` and that does not stop the submission work either. I tried: `return false; crawl(this);` isn't working either. – basickarl Aug 17 '16 at 14:13
  • @KarlMorrison — Well no. The `test` function still throws an exception. Jiggling around with the value of `onsubmit` isn't going to help. – Quentin Aug 17 '16 at 14:14
  • @Quentin I agree that my shorthand is not so readable. but if you catch all errors inside your function and return true on succesful start and false if there occured an error you can use the function somewhere else. – Raphael Müller Aug 17 '16 at 14:14
  • @RaphaelMüller I think that sounds like the best approach. – basickarl Aug 17 '16 at 14:15
  • 2
    @KarlMorrison you could also have a look at this [stackoverflow answer](http://stackoverflow.com/a/3350351/3641016), where they use an additional `preventDefault()` – Raphael Müller Aug 17 '16 at 14:22