Fetch api does not work in webextensions

I'm experimenting firefox webextensions. I'd like to make HTTP requests using the fetch API after submitting a form. The problem is that the fetch request is not doing anything.

Here is the data extracted from my manifest.json:

"browser_action": {
    "default_popup": "test.html"
  },
"permissions": [
    "<all_urls>"
 ],

Here is my test.html:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
</head>
<body>
<form>
    <button type="submit">Submit</button>
</form>
<script src="test.js"></script>
</body>
</html>

And here is my test.js:

document.querySelector("form").addEventListener("submit", fetchTest);
function fetchTest() {
    console.log("TEST");

    fetch('https://httpbin.org/get')
        .then(response => response.json())
        .then(response => {
            console.log(response);
            return response;
        })
        .catch(error => console.log(error));
}

When I click on the submit button of my form, I see that my function fetchTest is called because I can see the "TEST" message in the console. However, I have no requests coming from the browser in the "Network" panel, and I have no error in the console, it's as if the fetch() never happened.

Then, I tried to do the same thing with xhr:

function fetchTest() {
    console.log("TEST");

    const req = new XMLHttpRequest();
    req.open('GET', 'https://httpbin.org/get', false);
    req.setRequestHeader("Content-Type", "application/json");
    req.send(null);
    console.log(req);
}

With this version, everything is working just fine. I see the request in the "Network" panel and I have the data in my console.

Am I using the fetch API wrong ?

Thanks :)

Answers:

Answer

When an input of type submit is clicked, this causes a submit: since no other URL is specified, and no other form elements are there, the page is basically reloaded. Quoting MDN:

<input> elements of type "submit" are rendered as buttons. When the click event occurs (typically because the user clicked the button), the user agent attempts to submit the form to the server.

Your fetch-based solution is fully asynchronous, which means your code starts, but is interrupted by the reload before it is complete.

Your XHR-based solution succeeds, since you invoke a synchronous form of XHR (with false); the reload is stalled until your code finishes, then it still reloads.

You don't want a reload anyway, which destroys your JS state; you could prevent it by calling e.preventDefault() from the handler, but semantically it's more correct not to use a submit button instead of doing brain surgery on its semantics.

Using <input type="button"> (or better yet, <button>) would be the right (and cleaner) approach. Quoting MDN:

<input type="submit"> buttons are used to submit forms. If you want to create a custom button and then customize the behavior using JavaScript, you need to use <input type="button">, or better still, a <button> element.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.