JS WebAPIs and Website CORS

Posted on October 2, 2021
Tags: javascript

1 Content security policy

        <meta
            http-equiv="Content-Security-Policy"
            content="default-src '*'; frame-ancestors http://trialservice.byethost14.com/iplog.php" />

This example explains how this works:

The following requests use CORS.

By default all servers are same-origin. If we made a button on client that sends a fetch request to some server.

Access to fetch at 'http://server.com/hi.php' from origin 'http://client.com:8000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

Solution add Access-Control-Allow-Origin: http://client.com:8000 to the server response header by modifying the server’s code.

WARN: DO NOT CONFUSE the “cors” “no-cors” parameter in a fetch function. It is effectively meaningless whether you set it or not. All it does is show you an error or not, it will not give the client access to the server resource !

2 API’s

2.1 Audio

let flag = false
const audio = new Audio("https://raw.githubusercontent.com/bleh/bleh.github.io/master/bleh.mp3");
      audio.loop = true;
      document.getElementById("music").addEventListener("click",e=>{
        flag === false ? 
            (audio.play(), flag = true, e.target.innerText = "playing") : 
            (audio.pause(), flag = false, e.target.innerText = "paused");
        },false)

2.2 Clipboard

  document.addEventListener("click", e=>{
    navigator.clipboard.readText().then(
      clipText => document.getElementById("sometextdiv").innerText = clipText);
      })

2.3 Broadcast channel

      const chan = new BroadcastChannel('test_channel');
      chan.onmessage = function (event) { console.log(event); }
      document.getElementById("somebutton").addEventListener("click",e=>{
        chan.postMessage('This is a test message.');
      })

3 Send HTML request with js

let xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function() {
    if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
        let response = JSON.parse(xmlHttp.responseText);
        document.querySelector("div").innerHTML = response.value.joke;
    }
}
xmlHttp.open("GET", "https://api.icndb.com/jokes/random/", true);
xmlHttp.send(null);
let responseText = await fetch("https://api.icndb.com/jokes/random/")

It’s nearly impossible to set a promise respone to a variable but much easier with await

let somePromise = fetch("https://api.icndb.com/jokes/random/")
// We still cant do anything with this
let anotherPromise = responseTextPromise.then(response => response.text())
// nope this just returns another promise
let anotheranotherPromise = anotherPromise.then(x => x)

Notice when we use promises, this is no way to send the response to set a variable,
all we can do is infinitely chaining with more .then(..) which just returns yet another promise

4 Select element by class or id

document.querySelector("#content").value = "new value";
//this will select by id 

document.querySelector(".myclass");
//this will select by class 

5 More Complex selector

var el = document.querySelector("div.user-panel.main input[name='login']");
<div class="user-panel main">
    <input name="login"/>
</div>

6 Building HTML element through vanilla JS

var paragraph = document.createElement("p");
var textContent = document.createTextNode("content");
paragraph.appendChild(textContent);

document.querySelector("#messages").appendChild(paragraph);

7 Promises, Async, Timeout

sdfs


navigator.geolocation.getCurrentPosition((loc)=>{
    return `${loc.coords.latitude} and ${loc.coords.longitude}`
     })
//Local storage data is perm
localStorage.setItem("key", "someVal");
localStorage.getItem("key");

//Session storage data gets deletd on browser close
sessionStorage.setItem("key", "someVal");
sessionStorage.getItem("key");

8 location.hash

Not the hash function! Given a url: https://example.com/stuff#blah%20ads%20bah

location.hash –> #blah%20ads%20bah

decodeURIComponent(location.hash.substr(1))

9 JS for React

const callback = (e) => {
    const domTarget = e.target
    console.log(e.type)
}

List of event types

10 Web apis

11 this and bind

//global context
let dog = {
    //dog context
    sound : "wolf",
    talk : function(){ //note we didnt use arrow notation ()=>{}
        console.log(this.sound)
        //'this' -> dog context
    }
}
dog.talk() // prints wolf
let newdogtalk = dog.talk //we basically copied the talk function so 
//'this' now points to place of assignment which is global context
newdogtalk() //output undefined since there is no 'sound' in global


let newnewdogtalk = (dog.talk).bind(dog) //bind forces 'this' to point to dog context
newnewdogtalk() //output wolf

11.1 Arrow vs function()

  • Arrows binds this to the lexical scope, meaning you can just look at the code and see what encloses the arrow function to understand what this points to.
    • static binding
  • function() binds dynamically, meaning this depends on how the function is called at run time.
    • dynamic binding

12 Prototype give pseudo-class functionality to JS functions

JS has a half-baked class system which doesn’t actually have interfaces or abstract methods/classes. All you can do is extend concrete classes with concrete classes.

  1. JS functions can behave as pseudo-classes
  2. prototype allows to add methods to this psuedo-classes
  3. The clone() method in typical design pattern is just the new method applied to the JS pseudo-class
function Car(name) {
  this.name = name;
}
Car.prototype.getName = function(){
  console.log(this.name)
  return this.name
}
let b = new Car("sick")
b.getName()
const GenericPerson = {
  greet() {
    console.log(`hello, my name is ${this.name}!`);
  },
};

function Person(name) {
  this.name = name;
}

Object.assign(Person.prototype, GenericPerson);
// or
// Person.prototype.greet = GenericPerson.greet;

THIS is very similar to `Person extends GenericPerson` in OOP terms