AJAX



    <button onclick="ajax_ok()">ajax_ok</button>
    <input type="text" id="ajax_ok" value="php/ajax_json.php"/>
    <button onclick="ajax_abort()">ajax_abort</button>
    <input type="text" id="ajax_abort" value="php/ajax_abort.php"/>
  

    var ajax_results = document.getElementById("ajax_results");
    var ts = null;
    var loger = (x) => {
      ajax_results.innerHTML += x;
      ajax_results.innerHTML += " +"+(new Date()-ts)+"ms";
      ts = new Date();
    }
    function ajax_ok(){
      ts = new Date();
      ajax_results.innerHTML = "";
      ajax_request(
        document.getElementById("ajax_ok").value,
        loger,
        loger
      );
    }
    function ajax_abort(){
      ts = new Date();
      ajax_results.innerHTML = "";
      ajax_request(
        document.getElementById("ajax_abort").value,
        loger,
        loger
      );
    }
    function ajax_request(url, on_load, on_error) {
      var xhr = new XMLHttpRequest();
      xhr.onreadystatechange = function () {
        if (xhr.readyState === 4 && xhr.status === 200) {
          on_load(xhr.response + ", readyState - DONE [4]");
          loger(xhr.getAllResponseHeaders().trim().split(/[\r\n]+/).map((v)=>(v+" ")));
          // xhr.getResponseHeader("Last-Modified")
        } else {
          // loger(xhr.getAllResponseHeaders());
          switch(xhr.readyState){
            case 0:
              loger("readyState - UNSENT [0]");
              break;
            case 1:
              loger("readyState - OPENED [1]");
              break;
            case 2:
              loger("readyState - HEADERS_RECEIVED [2]");
              break;
            case 3:
              loger("readyState - LOADING [3]");
              break;
          }
        }
      }
      // every request will be unique, bypassing the cache
      xhr.open('GET', url + ((/\?/).test(url) ? "&" : "?") + (new Date()).getTime());
      // transaction starts transferring data
      xhr.onloadstart = function () {
        loger(url+", onloadstart");
      }
      // called periodically, before success completely
      xhr.onprogress = function (e) {
        if (e.lengthComputable) {
          loger(xhr.status+": "+xhr.statusText+" ["+(e.loaded/e.total*100)+"%], onprogress");
        } else {
          // Unable to compute progress information since the total size is unknown
          loger(xhr.status+": "+xhr.statusText+", onprogress");
        }
      }
      // request completed succesfully
      xhr.onload = function () {
        on_load(xhr.response);
      }
      xhr.onloadend = function(e) {
        loger(xhr.status+": "+xhr.statusText+" ["+(e.loaded/e.total*100)+"%], onloadend");
      }
      xhr.onabort = function () {
        loger(xhr.status+": "+xhr.statusText+", onabort");
      }
      xhr.ontimeout = function () {
        on_error(xhr.status+": "+xhr.statusText+", ontimeout: "+5000+"ms");
      }
      // transaction fails due to an error
      xhr.onerror = function () {
        on_error(xhr.status+": "+xhr.statusText+", "+xhr.response+", onerror");
      }
      xhr.send('');
      // xhr.send("foo=bar&lorem=ipsum");
      // xhr.send('string');
      // xhr.send(new Blob());
      // xhr.send(new Int8Array());
      // xhr.send(document);
    }
  

AJAX+XML

choose or click on catalog entry

    <input type="button" onclick="ax_cds.ax_prev()" value="ax_prev()">
    <input type="button" onclick="ax_cds.ax_next()" value="ax_next()">

    <div id="ax_info"></div>

    <table id="ax_catalog" style="cursor:pointer;"></table>
  

    var ax_catalog = document.getElementById("ax_catalog"),
        ax_info = document.getElementById("ax_info");

    const ax_cds = {
      ax_index: 0,
      ax_len: 0,
      ax_xml_catalog: "",
      show_entry(i) {
        var entry = this.ax_xml_catalog[i];
        ax_info.innerHTML = entry.getElementsByTagName("ARTIST")[0].childNodes[0].nodeValue;
        ax_info.innerHTML += " - ";
        ax_info.innerHTML += entry.getElementsByTagName("TITLE")[0].childNodes[0].nodeValue;
        ax_info.innerHTML += " [";
        ax_info.innerHTML += entry.getElementsByTagName("YEAR")[0].childNodes[0].nodeValue;
        ax_info.innerHTML += "]";
      },
      show_all() {
        table="<tr><th>Artist</th><th>Title</th><th>Year</th></tr>";
        for (i = 0; i < this.ax_len; i++) {
          table += "<tr onclick='ax_cds.show_entry(" + i + ")'><td>";
          table += this.ax_xml_catalog[i].getElementsByTagName("ARTIST")[0].childNodes[0].nodeValue;
          table += "</td><td>";
          table +=  this.ax_xml_catalog[i].getElementsByTagName("TITLE")[0].childNodes[0].nodeValue;
          table += "</td><td>";
          table +=  this.ax_xml_catalog[i].getElementsByTagName("YEAR")[0].childNodes[0].nodeValue;
          table += "</td></tr>";
        }
        ax_catalog.innerHTML = table;
      },
      load_xml(callback) {
        var obj = this;
        var xmlhttp = new XMLHttpRequest();
        xmlhttp.onreadystatechange = function() {
            if (this.readyState == 4 && this.status == 200) {
              obj.ax_xml_catalog = this.responseXML.getElementsByTagName("CD");
              obj.ax_len = obj.ax_xml_catalog.length;
              callback();
            } else {
              // ax_info.innerHTML = "unable to load XML-catalog";
            }
        };
        xmlhttp.open("GET", "cd_catalog.xml", true);
        xmlhttp.send();
      },
      ax_prev() {
        if (this.ax_index > 0) {
          this.show_entry(--this.ax_index);
        }
      },
      ax_next() {
        if (this.ax_index < this.ax_len-1) {
          this.show_entry(++this.ax_index);
        }
      }
    };
    ax_cds.load_xml(()=>{ax_cds.show_all()});
  

    <?xml version="1.0" encoding="UTF-8"?>
      <CATALOG>
        <CD>
          <TITLE>Empire Burlesque</TITLE>
          <ARTIST>Bob Dylan</ARTIST>
          <COUNTRY>USA</COUNTRY>
          <COMPANY>Columbia</COMPANY>
          <PRICE>10.90</PRICE>
          <YEAR>1985</YEAR>
        </CD>
        <CD>
          <TITLE>Hide your heart</TITLE>
          <ARTIST>Bonnie Tyler</ARTIST>
          <COUNTRY>UK</COUNTRY>
          <COMPANY>CBS Records</COMPANY>
          <PRICE>9.90</PRICE>
          <YEAR>1988</YEAR>
        </CD>
      ...
  

Forms

F.Name:
L.Name:
Age:
Email:
URL:
Pass (only numbers):
Country:
ZIP:
Select files smaller than 75 kB:


    <form
      name="myForm"
      action="/action_page.php"
      enctype="text/plain"
      onsubmit="return validateForm()"
      method="post"
    >
      F.Name: <input type="text" name="fname" maxlength="30" required value="First Name"/>
      L.Name: <input type="text" name="lname" maxlength="30" required value=""/>
      Age: <input type="number" name="age" min="1" max="30" value="50" />
      Email: <input type="email" name="email" value="wrong.email.com" />
      URL: <input type="url" name="url" value="right.address.com" />
      Pass: <input type="password" name="pass" pattern="[0-9]{4}" value="ABCD" />
      Country:
      <select id="Country">
        <option value="ch">Switzerland</option>
        <option value="fr">France</option>
        <option value="de">Germany</option>
        <option value="nl">The Netherlands</option>
      </select>
      ZIP: <input type="text"name="zip"/>
      Select files smaller than 75 kB: <input type="file" multiple id="input_files" />
      <input type="submit" value="Submit" />
      <span id="form_msg"></span>
    </form>
  

    var form_tests_result = document.getElementById("form_tests_result");

    function validateForm() {
      var fname = document.forms["myForm"]["fname"].value;
      var lname = document.forms["myForm"]["lname"].value;
      var age = document.forms["myForm"]["age"].value;
      var email = document.forms["myForm"]["email"].value;
      var url = document.forms["myForm"]["url"].value;
      var pass = document.forms["myForm"]["pass"].value;

      // CLASSIC check of input fields
      if (x == "") {
        alert("Name must be filled out");
        return false;
      }
      // If x is Not a Number or less than one or greater than 10
      if (isNaN(x) || x < 1 || x > 10) {
        alert("Age is not valid");
        return false;
      }

      // CONSTRAINTS
      document.forms["myForm"].checkValidity();  // false - some values are not filled
      age.checkValidity(); // false
      // invalid-event is fired every time checkValidity() is called
      document.getElementById('input-1').addEventListener('invalid', function() {
        //...
      }, false);

      fname.validity.valid; // true - valid fill (required with value)
      lname.validity.valueMissing; // true - input with required-attribute and no value

      fname.validationMessage; // false

      fname.validity.customError; // false
      fname.setCustomValidity('Invalid'); // set the validationMessage property of an input element
      fname.validity.customError; // true - custom validity message is set

      pass.validity.patternMismatch; // false - value does not match its pattern attribute

      document.forms["myForm"]["fname"].willValidate; //undefined

      age.validity.rangeOverflow; // true - value is greater than its max attribute
      age.validity.rangeUnderflow; // false - value is NOT less than its min attribute
      age.validity.stepMismatch; // false - value is valid per its step attribute

      name.validity.tooLong; // false

      email.validity.typeMismatch; // true - value is invalid per its type attribute
      url.validity.typeMismatch; // false - value is NOT invalid per its type attribute
    }

    // CONSTRAINTS functions for changes check
    function checkZIP() {
      // For each country, defines the pattern that the ZIP has to follow
      var constraints = {
        ch : [ '^(CH-)?\\d{4}$', "Switzerland ZIPs, exactly 4 digits: e.g. CH-1950 or 1950" ],
        fr : [ '^(F-)?\\d{5}$' , "France ZIPs, exactly 5 digits: e.g. F-75012 or 75012" ],
        de : [ '^(D-)?\\d{5}$' , "Germany ZIPs, exactly 5 digits: e.g. D-12345 or 12345" ],
        nl : [ '^(NL-)?\\d{4}\\s*([A-RT-Z][A-Z]|S[BCE-RT-Z])$',
              "Nederland ZIPs, exactly 4 digits, followed by 2 letters except SA, SD and SS" ]
      };
      var country = document.forms["myForm"]["country"].value; // Read the country id
      var ZIPField = document.forms["myForm"]["zip"]; // Get the NPA field
      var constraint = new RegExp(constraints[country][0], ""); // Build the constraint checker
      if (constraint.test(ZIPField.value)) { // Check it!
        // The ZIP follows the constraint, we use the ConstraintAPI to tell it
        ZIPField.setCustomValidity("");
      }
      else {
        // The ZIP doesn't follow the constraint, we use the ConstraintAPI to
        // give a message about the format required for this country
        ZIPField.setCustomValidity(constraints[country][1]);
        form_tests_result.innerHTML = constraints[country][1];
      }
    }
    function checkFileSize() {
      var input_files = document.getElementById("input_files");
      var fileList = input_files.files;
      // now here you can work with multiple files from list ...
      // if there is (at least) one file selected
      if (fileList.length > 0) {
        for (var i = 0, numFiles = fileList.length; i < numFiles; i++) {
          if (fileList[i].size > 75 * 1024) { // Check the constraint
            var msg = fileList[i].name+" must not be larger than 75 kB ["+fileList[i].size+" B already]";
            input_files.setCustomValidity(msg);
            form_tests_result.innerHTML += msg;
            return;
          }
        }
      }
      // No custom constraint violation
      input_files.setCustomValidity("");
    }
    window.onload = function () {
      document.forms["myForm"]["country"].onchange = checkZIP;
      document.forms["myForm"]["zip"].oninput = checkZIP;
      document.forms["myForm"]["input_files"].onchange = checkFileSize;
    }
  

AJAX+Forms

Form Receiver :

GET method

Registration example

First name:
Last name:


POST method

Registration example: application/x-www-form-urlencoded (default)

First name:
Last name:


Registration example: text/plain

Your name:

Your message:


Upload example: multipart/form-data

First name:
Last name:
Sex:
Password:
What do you prefer:

Post MULTIPLE photos:


Describe yourself:


RESPONSE

  
  

    <form
      action="php/form_submit.php"
      method="post"
      enctype="multipart/form-data"
      onsubmit="AJAXSubmit(this); return false;"
    >...

    <input type="file" multiple name="photos[]">
  

    "use strict";
    var AJAXSubmit = (function () {
      function ajaxSuccess () {
        document.getElementById("ajax_forms_results").innerHTML =
          this.responseText;
      }
      function submitData (data) {
        var xhr = new XMLHttpRequest();
        xhr.submittedData = data;
        xhr.onload = ajaxSuccess;
        if (data.technique == "get") {
          xhr.open(
            "get",
            data.receiver.replace(/(?:\?.*)?$/,
            data.segments.length > 0 ? "?" + data.segments.join("&") : ""),
            true
          );
          xhr.send(null);
        } else {
          xhr.open("post", data.receiver, true);
          if (data.technique == "mp-fd") {
            var sBoundary = "---------------------------" + Date.now().toString(16);
            xhr.setRequestHeader("Content-Type", "multipart\/form-data; boundary=" + sBoundary);
            xhr.sendAsBinary("--" + sBoundary + "\r\n" +
            data.segments.join("--" + sBoundary + "\r\n") + "--" + sBoundary + "--\r\n");
          } else {
            // enctype is application/x-www-form-urlencoded or text/plain
            xhr.setRequestHeader("Content-Type", data.contentType);
            xhr.send(data.segments.join(data.technique == "text" ? "\r\n" : "&"));
          }
        }
      }
      function processStatus (data) {
        if (data.status > 0) { return; }
        // form is now totally serialized! do something before sending it to the server...
        // doSomething(data);...
        // console.log("AJAXSubmit - The form is now serialized. Submitting...");
        submitData (data);
      }
      function pushSegment (fr_evt) {
        this.owner.segments[this.segmentIdx] += fr_evt.target.result + "\r\n";
        this.owner.status--;
        processStatus(this.owner);
      }
      function encode_uri(str) {
        return encodeURIComponent(str).replace(/[!'()*]/g, function(c) {
          return '%' + c.charCodeAt(0).toString(16);
        });
      }
      function SubmitRequest (form) {
        var field_type, field, file_reader, file_nr, file,
            is_post = form.method.toLowerCase() === "post";
        // serializing form...
        // mp-fd = multipart/form-data
        // text = text/plain
        // xform = application/x-www-form-urlencoded
        this.contentType = ((is_post && form.enctype) ?
                            form.enctype : "application\/x-www-form-urlencoded");
        this.technique = is_post ? this.contentType === "multipart\/form-data" ? "mp-fd"
            : this.contentType === "text\/plain" ? "text" : "xform" : "get";
        // this.receiver = form.action;
        this.receiver = document.getElementById("form_receiver").value;
        this.status = 0;
        this.segments = [];
        for (var form_input = 0; form_input < form.elements.length; form_input++) {
          field = form.elements[form_input];
          if (!field.hasAttribute("name")) { continue; }
          field_type = (( field.nodeName.toUpperCase() === "INPUT") ?
                          field.getAttribute("type").toUpperCase() : "TEXT");
          if (field_type === "FILE" && field.files.length > 0) {
            if (this.technique == "mp-fd") {
              for (file_nr = 0; file_nr < field.files.length; file_nr++) {
                file = field.files[file_nr];
                file_reader = new FileReader();
                // custom properties
                file_reader.segmentIdx = this.segments.length;
                file_reader.owner = this;
                // end of custom properties
                file_reader.onload = pushSegment;
                this.segments.push("Content-Disposition: form-data; name=\"" +
                    field.name + "\"; filename=\"" + encode_uri(file.name) +
                    "\"\r\nContent-Type: " + file.type + "\r\n\r\n");
                this.status++;
                file_reader.readAsBinaryString(file);
              }
            } else {
              // application/x-www-form-urlencoded or text/plain
              // or GET and files will not be sent!
              for (
                file_nr = 0;
                file_nr < field.files.length;
                this.segments.push(
                  encode_uri(field.name) + "=" + encode_uri(field.files[file_nr++].name)
                )
              );
            }
          } else if (
            (field_type !== "RADIO" && field_type !== "CHECKBOX") || field.checked
          ) {
            // submit _all_ submit buttons
            // field type is not FILE or is FILE but is empty
            if (this.technique == "mp-fd") {
              this.segments.push(
                "Content-Disposition: form-data; name=\"" +
                field.name + "\"\r\n\r\n" + field.value + "\r\n"
              );
            } else {
              // application/x-www-form-urlencoded or text/plain or method is GET
              this.segments.push(
                encode_uri(field.name) + "=" + encode_uri(field.value)
              );
            }
          }
        }
        processStatus(this);
      }
      return function (form) {
        if (!form.action) { return; }
        new SubmitRequest(form);
      };
    })();
    if (!XMLHttpRequest.prototype.sendAsBinary) {
      XMLHttpRequest.prototype.sendAsBinary = function(sData) {
        var nBytes = sData.length, ui8Data = new Uint8Array(nBytes);
        for (var nIdx = 0; nIdx < nBytes; nIdx++) {
          ui8Data[nIdx] = sData.charCodeAt(nIdx) & 0xff;
        }
        // send as ArrayBufferView...
        this.send(ui8Data);
        // or as ArrayBuffer (legacy)...: this.send(ui8Data.buffer); */
      };
    }
  

FormData


    function fd_tests_submit () {
      var fd_tests_result = document.getElementById("fd_tests_result");
      var fd_form = document.getElementById('fd_form');
      var fd = new FormData(fd_form);
      fd_tests_result.innerHTML = "";
      for(var pair of fd) {
        fd_tests_result.innerHTML += pair[0]+ ' = '+ pair[1];
      }
      fd_tests_result.innerHTML += "-----keys-----";
      for (var key of fd.keys()) {
        fd_tests_result.innerHTML += key;
      }
      fd_tests_result.innerHTML += "-----values-----";
      for (var value of fd.values()) {
        fd_tests_result.innerHTML += value;
      }
      fd_tests_result.innerHTML += "-----file-----";
      fd_tests_result.innerHTML += fd.get('userfile').name;
      fd_tests_result.innerHTML += fd.get('userfile').type;
      fd_tests_result.innerHTML += fd.get('userfile').size;
      fd_tests_result.innerHTML += fd.get('userfile').lastModified;
    }

    var formData = new FormData(); // Currently empty
    formData.append('username', 'Chris'); // add a key/value pair
    formData.append('userpic', myFileInput.files[0], 'chris.jpg');
    formData.append('this_thing', 'will be deleted');
    formData.delete('this_thing');
    formData.get('username'); // Returns "Chris"
    formData.append('username', 'Bob');
    formData.getAll('username'); // Returns ["Chris", "Bob"]
  

AJAX+FormData

Form Receiver :

GET method

First name:
Last name:


POST method

Enctype: application/x-www-form-urlencoded (default)

First name:
Last name:


Enctype: multipart/form-data

First name:
Last name:
Sex:
Password:
What do you prefer:

Post MULTIPLE photos:


Describe yourself:


RESPONSE

  
  

    <form
      action="php/form_submit.php"
      method="post"
      enctype="multipart/form-data"
      onsubmit="fd_AJAXSubmit(this); return false;"
    >...

    <input type="file" multiple name="photos[]">
  

    "use strict";
    function ajaxSuccess () {
      console.log(this.responseText);
    }
    function AJAXSubmit (form_el) {
      if (!form_el.action) { return; }
      var xhr = new XMLHttpRequest();
      xhr.onload = ajaxSuccess;
      if (form_el.method.toLowerCase() === "post") {
        xhr.open("post", form_el.action);
        xhr.send(new FormData(form_el));
      } else {
        var field, file_type, file_nr, search_str = "";
        for (var nItem = 0; nItem < form_el.elements.length; nItem++) {
          field = form_el.elements[nItem];
          if (!field.hasAttribute("name")) { continue; }
          file_type = field.nodeName.toUpperCase() === "INPUT" ?
              field.getAttribute("type").toUpperCase() : "TEXT";
          if (file_type === "FILE") {
            for (file_nr = 0; file_nr < field.files.length;
                search_str += "&" + escape(field.name) + "=" + escape(field.files[file_nr++].name));
          } else if ((file_type !== "RADIO" && file_type !== "CHECKBOX") || field.checked) {
            search_str += "&" + escape(field.name) + "=" + escape(field.value);
          }
        }
        xhr.open("get", form_el.action.replace(/(?:\?.*)?$/, search_str.replace(/^&/, "?")), true);
        xhr.send(null);
      }
    }
  

Fetch


    if (self.fetch) {
      // run my fetch request here
    } else {
      // do something with XMLHttpRequest?
    }

    var ftr = document.querySelector('#fetch_tests_result');

    var myHeaders = new Headers({'Content-Type': 'application/json'});
    // same as: new Headers([['Content-Type', 'application/json']]);
    // myHeaders.get('Content-Type') // should return 'application/json'
    var myInit = {
      method: 'POST',
      headers: myHeaders,
      //headers: { 'Content-Type': 'image/jpeg' },
      mode: 'cors',
      cache: 'default'
    };
    var myRequest = new Request('php/ajax_json.php');

    // same as:
    // var myRequest = new Request('php/ajax_json.php', {method: 'POST',... });

    var newRequest = myRequest.clone(); // a copy of the request is now stored in newRequest
    // or: var newRequest = new Request(myRequest, myInit);

    // myRequest.url; // http://web-engineer-book/php/ajax_json.php
    // myRequest.method; // POST
    // myRequest.credentials; // same-origin
    // myRequest.bodyUsed; // true

    fetch(myRequest).then(function(response) {
      var contentType = response.headers.get("content-type");
      if (
        response.ok &&
        contentType &&
        contentType.includes("application/json")
      ) {
        return response.json();
      }
      throw new Error('Network response was not ok.');
    }).then(function(response) {
      for (chapter in response) {
        ftr.innerHTML += chapter;
        for (chapter_data in response[chapter]) {
          ftr.innerHTML += response[chapter][chapter_data];
        }
      }
    })
    // get image content
    // .then(response => response.blob())
    // .then(blob => {
    //   myImage.src = URL.createObjectURL(blob);
    // })
    .catch(error => {
      console.error(error);
    });

    // ----------

    var myBlob = new Blob();
    var init = { "status" : 200 , "statusText" : "SuperSmashingGreat!" };
    var myResponse = new Response(myBlob,init);

    // ---------- example POST method implementation

    postData(`http://example.com/answer`, {answer: 42})
      .then(data => console.log(JSON.stringify(data))) // JSON-string from `response.json()` call
      .catch(error => console.error(error));

    function postData(url = ``, data = {}) {
      // Default options are marked with *
      return fetch(url, {
        method: "POST", // *GET, POST, PUT, DELETE, etc.
        mode: "cors", // no-cors, cors, *same-origin
        cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached
        credentials: "same-origin", // include, same-origin, *omit
        headers: {
            "Content-Type": "application/json; charset=utf-8",
            // "Content-Type": "application/x-www-form-urlencoded",
        },
        redirect: "follow", // manual, *follow, error
        referrer: "no-referrer", // no-referrer, *client
        body: JSON.stringify(data), // body data type must match "Content-Type" header
      })
      .then(response => response.json()); // parses response to JSON
    }

    // ---------- upload JSON data

    var url = 'https://example.com/profile';
    var data = {username: 'example'};
    fetch(url, {
      method: 'POST', // or 'PUT'
      body: JSON.stringify(data), // data can be `string` or {object}!
      headers:{
        'Content-Type': 'application/json'
      }
    }).then(res => res.json())
    .then(response => console.log('Success:', JSON.stringify(response)))
    .catch(error => console.error('Error:', error));

    // ---------- upload FILE

    var formData = new FormData();
    var fileField = document.querySelector("input[type='file']");
    formData.append('username', 'abc123');
    formData.append('avatar', fileField.files[0]);
    fetch('https://example.com/profile/avatar', {
      method: 'PUT',
      body: formData
    })
    .then(response => response.json())
    .catch(error => console.error('Error:', error))
    .then(response => console.log('Success:', JSON.stringify(response)));

    // ---------- upload multiple FILES

    var formData = new FormData();
    var photos = document.querySelector("input[type='file'][multiple]");
    formData.append('title', 'My Vegas Vacation');
    formData.append('photos', photos.files);
    fetch('https://example.com/posts', {
      method: 'POST',
      body: formData
    })
    .then(response => response.json())
    .then(response => console.log('Success:', JSON.stringify(response)))
    .catch(error => console.error('Error:', error));
  
new object's type creating constructor guard setting of associated Headers
Request Request() request
Request() with mode of no-cors request-no-cors
Response Response() response
error() or redirect() methods immutable

URL interface

tests link

    var url_tests = document.getElementById("url_tests");
    var link = document.getElementById("tests_link");
    var url = new URL("https://usr:psw@dev.moz.org:123/en-US/docs/Hyper?yes=1&no=0#ooops");
    var obj = {key: url};
    var url_2 = new URL("../cats", url);

    url_tests.innerHTML +=
    "link.toString(): " + link.toString() +
    "link.hostname: " + link.hostname +
    "url.href: " + url.href +
    "url.origin: " + url.origin +
    "url.host: " + url.host +
    "url.protocol: " + url.protocol +
    "url.hostname: " + url.hostname +
    "url.port: " + url.port +
    "url.pathname: " + url.pathname +
    "url.search: " + url.search +
    "url.searchParams.get('yes'): " + url.searchParams.get('yes') +
    "url.hash: " + url.hash +
    "url.username: " + url.username +
    "url.password: " + url.password +
    "JSON.stringify(obj): " + JSON.stringify(obj) +
    "------------------------------------------------";
    url_tests.innerHTML +=
    "url_2.href: " + url_2.href;
    url_2.hash = 'cat';
    url_tests.innerHTML +=
    "url_2.href: " + url_2.href;
    url_2.pathname = 'демон.html';
    url_tests.innerHTML +=
    "url_2.href: " + url_2.href;

    const response = await fetch(new URL('http://www.example.com/демон.html'));

    (new URL(document.location)).searchParams

    // https://developer.mozilla.org/
    var a = new URL("/", "https://developer.mozilla.org");
    // https://developer.mozilla.org/
    var b = new URL("https://developer.mozilla.org");
    // https://developer.mozilla.org/en-US/docs
    var c = new URL('en-US/docs', b);
    // https://developer.mozilla.org/en-US/docs
    var d = new URL('/en-US/docs', b);
    // https://developer.mozilla.org/en-US/docs
    var f = new URL('/en-US/docs', d);
    // https://developer.mozilla.org/en-US/docs
    var g = new URL('/en-US/docs', "https://developer.mozilla.org/fr-FR/toto");
    // https://developer.mozilla.org/en-US/docs
    var h = new URL('/en-US/docs', a);
    // TypeError exception as '' is not a valid URL
    var i = new URL('/en-US/docs', '');
    // TypeError exception as '/en-US/docs' is not a valid URL
    var j = new URL('/en-US/docs');
    // http://www.example.com/
    var k = new URL('http://www.example.com', 'https://developers.mozilla.com');
    // http://www.example.com/
    var l = new URL('http://www.example.com', b);
  

FileReader


    <input type="file" id="fr_file"/>
    <select id="frr">
      <option value="t">readAsText()</option>
      <option value="ab">readAsArrayBuffer()</option>
      <option value="bs">readAsBinaryString()</option>
      <option value="du">readAsDataURL()</option>
    </select>
    <button onclick="readWithFileReader()">Read with FileReader()</button>
    <button onclick="canvasToBlob()">Canvas to Blob</button>
  

    var fr_result = document.getElementById("fr_result");
    var fr_content = document.getElementById("fr_content");

    // var fileInput = document.querySelector('input[type="file"]');
    function readWithFileReader() {
      // var file = fileInput.files.item(0);
      var file = document.getElementById("fr_file").files.item(0),
          reader = new FileReader(),
          frr = document.getElementById("frr").value;
      fr_result.innerHTML = 'reader.readyState = EMPTY [0]';
      reader.onabort = ()=>{fr_result.innerHTML+='ABORTED'};
      reader.onerror = ()=>{fr_result.innerHTML+='ERROR'};
      reader.onloadstart = ()=>{fr_result.innerHTML+='LOAD START'};
      reader.onprogress = ()=>{fr_result.innerHTML+='PROGRESS'};
      // each time the reading operation is completed (success or failure)
      reader.onloadend = ()=>{fr_result.innerHTML+='LOAD END'};
      try {
        if (frr == 'ab') {
          reader.readAsArrayBuffer(file);
        } else if (frr == 'bs') {
          reader.readAsBinaryString(file);
        } else if (frr == 'du') {
          reader.readAsDataURL(file);
        } else {
          reader.readAsText(file);
        }
        fr_result.innerHTML += 'reader.readyState = LOADING [1]';
        // reading operation is successfully completed
        reader.onload = function () {
          fr_result.innerHTML += 'reader.readyState = DONE [2]';
          fr_content.innerHTML = reader.result;
        };
        return;
      } catch (e) {
        fr_result.innerHTML += e; return;
      } finally {
        fr_result.innerHTML += 'should be readed already...';
      }
    }

    function canvasToBlob () {
      var canvas = document.createElement('canvas');
      var height = 200;
      var width  = 200;
      canvas.width  = width;
      canvas.height = height;
      var ctx = canvas.getContext('2d');
      ctx.strokeStyle = '#090';
      ctx.beginPath();
      ctx.arc(width/2, height/2, width/2 - width/10, 0, Math.PI*2);
      ctx.stroke();
      canvas.toBlob(function (blob) {
        var reader = new FileReader();
        reader.onloadend = function () {
          fr_result.innerHTML = '';
          fr_content.innerHTML = reader.result;
        }
        reader.readAsDataURL(blob);
      });
    }
  

Files tricks

Select one or multiple files and output them in below sections by type:

or drop files here from OS :)


    <div id="filestricks" class="example"
      ondragenter="prevent_all(event)"
      ondragover="prevent_all(event)"
      ondrop="f_drop(event)"
    >
      Select one or multiple files and output them in below sections by type:
      <input id="trick_files" type="file" onchange="trickFilesSize(this);" multiple>
      <label for="trick_files">LABEL element for #trick_files</label>
      <button onclick="trickFileHide()">trickFileHide()</button>
      <button onclick="trickFileClick()">trickFileClick()</button>
      <input type="text" value="php/form_submit.php" id="trick_upload_url"/>
      <button onclick="tricksFilesUpload()">tricksFilesUpload()</button>
      or drop files here from OS :)
    </div>
    <div id="filestricks_result" class="example"></div>
    <div id="filestricks_log" class="example"></div>
    <iframe
    id="pdf_viewer"
    class="example"
    ></iframe>
    <video controls style="height:300px;width:48%;" id="trick_video"></video>
    <audio controls style="height:300px;width:48%;" id="trick_audio"></audio>
  

    var filestricks = document.getElementById("filestricks");
    var fs_res = document.getElementById("filestricks_result");
    var fs_log = document.getElementById("filestricks_log");
    var pdf_viewer = document.getElementById("pdf_viewer");
    var trick_video = document.getElementById("trick_video");
    var trick_audio = document.getElementById("trick_audio");

    var trick_files = document.getElementById("trick_files");
    var trick_upload_url = document.getElementById("trick_upload_url").value;

    // input id="trick_files" type="file" onchange="trickFilesSize(this);" multiple
    function trickFilesSize(el) {
      showInfo(trick_files.files);
    }

    function showInfo(all_files) {
      var total_bytes = 0,
          total_files = all_files.length,
          total_bytes = 0,
          files_desc = "";
      fs_res.innerHTML = total_files+" file(s):";
      for (var file_nr = 0; file_nr < total_files; file_nr++) {
        files_desc += all_files[file_nr].name+" = ";
        files_desc += sizeDesc(all_files[file_nr].size)+" ["+all_files[file_nr].type+"]";
        total_bytes += all_files[file_nr].size;
        if (all_files[file_nr].type.startsWith('image/')){
          // using FileReader
          var reader = new FileReader();
          reader.onload = function(e) {
            var img = document.createElement("img");
            img.setAttribute("height","50px");
            img.src = e.target.result;
            fs_res.appendChild(img);
          };
          reader.readAsDataURL(all_files[file_nr]);
          // // using URL
          // var img = document.createElement("img");
          // img.setAttribute("height","50px");
          // img.src = window.URL.createObjectURL(all_files[file_nr]);
          // fs_res.appendChild(img);
          // img.onload = function() {
          //   window.URL.revokeObjectURL(this.src);
          // }
        }
        // ERRORS !?
        if (all_files[file_nr].type == 'application/pdf'){
          var obj_url = pdf_viewer.setAttribute(
            'src',
            window.URL.createObjectURL(all_files[file_nr])
          );
          window.URL.revokeObjectURL(obj_url);
        }
        if (all_files[file_nr].type.startsWith('audio/')){
          var obj_url = trick_audio.setAttribute(
            'src',
            window.URL.createObjectURL(all_files[file_nr])
          );
          window.URL.revokeObjectURL(obj_url);
        }
        if (all_files[file_nr].type.startsWith('video/')){
          var obj_url = trick_video.setAttribute(
            'src',
            window.URL.createObjectURL(all_files[file_nr])
          );
          window.URL.revokeObjectURL(obj_url);
          // video.play()
        }
      }
      fs_res.innerHTML += files_desc;
      fs_res.innerHTML += "TOTAL SIZE: "+sizeDesc(total_bytes);
    }
    function sizeDesc (bytes) {
      var res = bytes+" bytes"
      for (
        var byte_types = ["Kb", "Mb", "Gb", "Tb", "Pb", "Eb", "Zb", "Yb"],
        byte_type = 0,
        b = bytes / 1024;
        b > 1;
        b /= 1024,
        byte_type++
      ) {
        res = b.toFixed(3) + " " + byte_types[byte_type]
      }
      return res;
    }

    function tricksFilesUpload() {
      fs_log.innerHTML = "";
      for (var file_nr = 0; file_nr < trick_files.files.length; file_nr++) {
        fs_log.innerHTML += trick_files.files[file_nr].name;
        fileUpload(trick_files.files[file_nr]);
      }
    }
    function fileUpload(file) {
      var xhr = new XMLHttpRequest();
      xhr.upload.addEventListener("progress", function(e) {
        if (e.lengthComputable) {
          var percentage = Math.round((e.loaded * 100) / e.total);
          fs_log.innerHTML += percentage+"%";
        }
      }, false);
      // xhr.upload.addEventListener(
      //   "load", // abort, error, ...
      //   (e) => {fs_log.innerHTML += "100%"},
      //   false
      // );
      xhr.open(
        "POST",
        trick_upload_url
      );
      xhr.overrideMimeType('text/plain; charset=x-user-defined-binary');
      var reader = new FileReader();
      reader.onload = (e) => {xhr.send(e.target.result)};
      reader.readAsBinaryString(file);
    }

    function prevent_all(e) {
      e.stopPropagation();
      e.preventDefault();
    }
    function f_drop(e) {
      e.stopPropagation();
      e.preventDefault();
      showInfo(e.dataTransfer.files)
    }

    function trickFileHide() {
      if (trick_files.style.display === "none") {
        trick_files.style.display = "block";
      } else {
        trick_files.style.display = "none";
      }
    }
    function trickFileClick() {
      trick_files.click();
    }
  

Back to Main Page