Search code examples
htmlformsxmlhttprequestfetch

Which fetching API does HTML form uses? XHR or Fetch


How to find out which fetching API does a DOM component like HTML form uses while making http requests?

Edit: Is it possible to modify it from using one instead of another?


Solution

  • HTML Forms are using the http protocol to send and receive data and not XHR or Fetch (which are however also using that protocol)

    You cannot modify the form submission to use fetch or xmlhttprequest instead of the default protocol.

    If you you, as the owner/developer of the web page do not want to use the default functionality of a form, then you can hook the submit event and use preventDefault to stop the submission and use your own implementation using for example fetch or XHR.

    You do not even NEED a form to use fetch or xmlhttprequest, just gather the data using form elements and an optional button

    If it is not your page, you can look in the console in the network tab to see what is used to send data to the server:

    enter image description here

    Normal post (testing using POST and a form tester URL)

    enter image description here

    Example:

    NOTE1: StackOverflow does not allow writing to embedded iframes. To see the script below use the iframe, see this fiddle

    NOTE2: The whole idea of using fetch or xmlhttprequest will fail if the server in the action of the form does not support CORS!

    window.addEventListener("DOMContentLoaded", () => { // when page is loaded
      const form = document.getElementById("myForm");
      form.addEventListener("submit", (e) => {
        e.preventDefault(); // stop submission
        const tgt = e.target; // the form
        console.log(tgt.action)
        fetch(tgt.action, // the URL
            {
              "method": tgt.method,
              body: new FormData(tgt) // the content of the form
            }
          )
          .then(response => response.text()) // return the text
          .then(text => {
            console.log(text);
            try {
              const targetFrameDocument = document.getElementById(tgt.target).contentWindow.document;
              targetFrameDocument.write(`<pre>${text}</pre>`); // the pre is not needed if the site returns html
              targetFrameDocument.close();
            } catch (err) {
              const msg = err.message;
              console.log(msg.includes("cross-origin") ? "Sorry this site does not support iframe writing, see the fiddle instead" : msg);
            }
          });
      });
    });
    <form id="myForm" action="https://httpbin.org/post" method="POST" target="iframe1">
      <input type="text" name="field1" value="" placeholder="Type something and hit enter" />
      <input type="submit" name="anyNameBUTSubmit" value="Optional Submit button" />
    </form>
    
    <iframe name="iframe1" id="iframe1" src="about:blank"></iframe>