JavaScript
Value type and reference type
Value types
let a = 100;
let b = a;
console.log(b)/ / 100
Copy the code
Reference types
Common reference types
let a = { b: 100 };
let c = a;
a.b = 200;
console.log(c.b);/ / 200
Copy the code
conclusion
- Value types are stored on the stack
- The reference type, via a heap address, is stored in the heap. Look it up from the heap by address when needed (this is the idea of all computer programming)
Common value types
let a;// undefined
const b = 10;// number
const c = 'string';
const d = Symbol('sym');// symbol
const e = true;// boolean
Copy the code
Common reference types
const arr = [1.2.3];// Array
const obj = { a: 1 };// object
const n = null // Special reference type, pointer to an empty address
// Special reference type, but not used to store data, so there is no "copy copy function"
function fn() {} // The function type is executable
Copy the code
typeof
- Identify all value types
- Identify the function
typeof function () {}
//function
- Determine if it is a reference type (but not subdivided)
function deepClone(obj) {
if (typeofobj ! = ="object" || obj == null) {
return obj;
}
let result;
if (obj instanceof Object) {
result = {};
} else {
result = [];
}
for (let key in obj) {
if(obj.hasOwnProperty(key)) { result[key] = deepClone(obj[key]); }}return result;
}
const person = {
name: "zhangsan".age: 10.address: {
city: "shanghai".house: {
number: 1}},arr: ["a".1."b"]};const Lisi = deepClone(person);
person.name = "lisi";
person.address.city = "guangzhou";
console.log(Lisi.name);
console.log(Lisi.address.city);
Copy the code
instanceof
- detection
prototype
Property appears on the stereotype chain of an instance object
function Car(make, model, year) {
this.make = make;
this.model = model;
this.year = year;
}
let instanseCar = new Car('make'.'model'.1924);
console.log(instanseCar instanceof Car); // true
console.log(instanseCar instanceof Object); // true
Copy the code
Deep-copy objects
- A value type
- Have reference type
let objA = {
age: 10.name: 'zhangsan'.address: {
city: 'shanghai'
},
arr: [1.'str'.2]}Copy the code
TODO: Handwritten deep copy
Ideas:
- Value type or NULL, returned directly
- It is an object or an array
- Iterate through an object or array as a property of its own, not a property of the prototype chain, recursively
Variable calculation
String splicing
const a = 100 + 10 / / 110
const b = 100 + '10' / / '10010'
const c = true + '10' // 'true10'
const d = 100 + parseInt('10') / / 110
Copy the code
== operator conversion
100= ='100' // true
0= =' ' // true
false= =' ' // true
0= =false // true
null= =undefined // true
// Tip: use === unless == null
// eg:
const obj = { x: 100 }
console.log(obj.a == null) / / true, is equivalent to obj. A = = = null | | obj. A = = = is undefined
Copy the code
If statements and logic calculation (&& | |! With or not)
The IF statement judges truly and False variables, not true and false
- The TRULY variable:!! a === true
- Services Variable:!! b === false
The following are services variables and the rest are TRULY variables!!!!!undefined= = =false!!!!!0= = =false!!!!!' '= = =false!!!!!false= = =false!!!!!NaN= = =false!!!!!null= = =false
Copy the code
Prototype and prototype chain
The problem
- How to determine if a variable is an Array: an instanceof Array
- What is the nature of the class prototype?
- Write a simple jQuery, think plugins and extensibility: a great way to learn classes and prototypes
- Implement the basic API: Get each on
- Get familiar with the jQuery methods: each, get, and on
- Implement simple jQuery
- Considering the plugin
- Consider scalability: integration
- Implement the basic API: Get each on
class jQuery {
constructor(selector) {
const result = document.querySelectorAll(selector);
const length = result.length;
for (let i = 0; i < length; i++) {
this[i] = result[i];
}
this.length = length;
this.selector = selector;
}
get(index) {
return this[index];
}
each(fn) {
for (let i = 0; i < this.length; i++) {
const elem = this[i]; fn(elem); }}on(type, fn) {
return this.each((elem) = > {
elem.addEventListener(type, fn, false);
});
}
// Extend many DOM apis
}
/ / the plugin
jQuery.prototype.dialog = function (info) {
alert(info);
};
// Make the wheel
class myJQuery extends jQuery {
constructor(selector) {
super(selector);
}
// Extend your methods
addClass(className) {}
style(data){}}// const $p = new jQuery('p')
// $p.get(1)
// $p.each((elem) => console.log(elem.nodeName))
// $p.on('click', () => alert('clicked'))
Copy the code
A class of ES6
inheritance
- extends
- super
- Extend or override methods
Implicit and explicit archetypes
Let’s see by example
Codepen code
/ / parent class
class People {
constructor(name) {
this.name = name;
}
eat() {
console.log(this.name + " eat something"); }}/ / subclass
class Student extends People {
constructor(name) {
super(name);
}
sayHi() {
console.log(this.name + " say hi!!!"); }}class Teacher extends People {
constructor(name) {
super(name); }}let xiaoming = new Student("xiaoming");
console.log(xiaoming instanceof Student); // true
// ES6 class is function
console.log(typeof Student); // "function"
console.log(typeof People); // "function"
// Prototype chain: The implicit prototype of the instance points to the corresponding class's prototype
console.log(xiaoming.__proto__ === Student.prototype); // true
console.log(Student.prototype.__proto__ === People.prototype); // true
console.log(JSON.stringify(People.prototype));
console.log(xiaoming.sayHi());
console.log(xiaoming.eat());
Copy the code
Prototype relationship
- Each class has a display prototype prototype
- Each instance has an implicit prototype __proto__
- The instance’s __proto__ points to the prototype corresponding to the class
Based on stereotype execution rules, when obtaining properties or executing methods
- Start by looking at its own properties or methods
- If you can’t find it, look it up in __proto__.
- If you can’t find it, continue along the prototype chain until Object.prototype.__proto__ is null
For example, when xialuo. SayHi () is executed, it looks in the Xialuo instance itself. If it does not find any, it looks in xialuo
Understand and draw prototype chain diagrams
Scope and closure
The problem
- What is the
scope
? What is a free variable? - What is the
closure
? What are the application scenarios of closures? this
What kinds of assignments are there? How to set the value in application scenarios?- handwritten
bind
function
scope
- Global scope
- Function scope
- Block-level scope (new in ES6) : Let, const variables have block-level scope, which can be used inside {}
if (true) {
let a = 1;
}
console.log(a);// The value of a cannot be read outside the block scope. A is not defined
Copy the code
Free variables
A variable x that is used in scope A is not declared in scope A (that is, declared in other scopes). For scope A, x is A free variable.
- A variable is not defined in the current scope, but is used
- Search through the upper scope layer by layer until it is found
- If the global scope is not found, an error is reported: x is not defined
The functions in the lower closure are represented as arguments: all free variable look-ups are made to the parent scope where the function is defined, not where it is executed
closure
- Closures are special cases of scopes
- Function as the return value
function create() { let a = 100; return function() { console.log(a) } } let fn = create() let a = 200; fn();// What is the result? / / 100 Copy the code
- Function as argument
function create(fn) { let a = 200; fn(); } let a = 100; let fn = function() { console.log(a) } create(fn); // The result is 100: all free variable lookups are in the function definition, in the parent scope, not in the execution place Copy the code
Name the values of this in the following cases
- Call it as a normal function
- Use call bind apply
- Called as an object method
- Called in the class method
- Arrow function
What value does this take when it is executed in a function, as opposed to when it is defined as a free variable
function fn1() {
console.log(this)
}
fn1() // window
fn1.call({ x: 100}){x: 100}
const fn2 = fn1.bind({ x: 200 })
fn2()Bind {x: 200} {x: 200}
Copy the code
Codepen. IO/huangzonggu…
Scope-related issues
- How to value this in different application scenarios?
- Called as a normal function: this refers to the window
- Use Call bind apply: to point to the binder
- Called as an object method: refers to the current object
- Called in the class method: the class instance itself
- Arrow function: points to the value of the previous scope
- Arrow function expressionThe syntax thanFunctional expressionIt’s simpler, and it doesn’t have its own
this
.arguments
.super
ornew.target
.
- Arrow function expressionThe syntax thanFunctional expressionIt’s simpler, and it doesn’t have its own
- Handwritten bind
- The application scenarios of closures in actual development are illustrated with examples
- Hiding data is like creating a cache to store data that is not called by the outside world
This in the prototype chain
class People {
constructor(name) {
this.name = name; }}class Student extends People {
constructor(name, number) {
super(name);
this.number = number;
}
sayHi() {
console.log(Name of `The ${this.name}Student idThe ${this.number}`); }}const stu1 = new Student("xialuo"."123");
stu1.sayHi();// "Name Xialuo student number 123"
stu1.__proto__.sayHi();// "name undefined student id undefined"
// obj.__proto__. Fun () this refers to obj.__proto__, which has no name or number
// The actual obj.fun() works like obj.__proto__fun.call (obj) this points to obj
// console.log(stu1);
// console.log(stu1.__proto__);
Copy the code
Task: Application scenario for closures
1.Image stabilization
// Buffering: trigger multiple times in a row, only perform the last time; Application scenario: Input is entered continuously, button is clicked several times
// throttling: trigger many times continuously, trigger only once within a certain period of time; Application scenario: Read the position of the mouse when the mouse moves
const fn = () = > console.log("fn");
window.onresize = debounce(fn, 500);
function debounce(fn) {
let timer;
return function () {
if (timer) {// The timer is stored in memory after the first execution and remains an executor until it is finally triggered
clearTimeout(timer);
}
timer = setTimeout(() = > fn(), 500);
};
}
Copy the code
2.Design singleton patterns using closures
// Singleton mode: When multiple instances are created, only one instance can be created
class createUser {
constructor(name) {
this.name = name; }}// let a = new createUser("aa");
// console.log(a.name);
// The agent creates the singleton pattern
const ProxyFun = (() = > {
let instance = null;
Closures access internal variables by returning functions
return function (name) {
if(! instance) { instance =new createUser(name);
}
returninstance; }; }) ();// Execute immediately, return function
const b = ProxyFun("b");
const c = ProxyFun("c");
console.log(b.name, c.name);
console.log(b === c);
Copy the code
- Reference: juejin. Cn/post / 684490…
asynchronous
- Question 1: Single threaded vs. asynchronous (the difference between synchronous and asynchronous)?
- Js is a single-threaded language that can only do one thing at a time
- Browsers and NodeJS already support JS startup
process
如Web Worker
- JS and DOM rendering share the same thread because JS can modify the DOM structure
- Do not get stuck when waiting (network request, scheduled task)
- Stuck problems need to be resolved asynchronously
- Alert is synchronization and blocks code execution
- SetTimeout is asynchronous and does not block execution
- Callback function form
- Problem two: Load an image by hand with a Promise
// Load picture Fun after success and failure processing
const loadImage = (url) = > {
return new Promise((resolve, reject) = > {
let img = document.createElement("img");
img.onload = () = > {
resolve(img);
document.body.appendChild(img);
};
img.onerror = () = > {
reject(new Error("load image error"));
};
img.src = url;
});
};
const url =
"https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__480.jpg";
loadImage(url)
.then((data) = > {
console.log('width: ', data.width);
return data;
})
.then((data) = > {
console.log('height: ', data.height);
})
.catch((error) = > console.error(error));
Copy the code
- Problem 3: Asynchronous front-end application scenarios
- Web requests such as Ajax image loading
- Scheduled tasks setTimeout and setInteral
The relevant knowledge
- Single threaded and asynchronous
- Application scenarios
- The callback hell and Promise
event loop
Be able to draw a picture and describe the process
Diagram component
- Browser console
- Call Stack
- Web APIs(similar to setTimeout)
- Callback Queue(Event Loop)
Event Loop(event polling/event Loop) process
- Synchronizes code and executes it line by line on the Call Stack
- When you encounter asynchronous code, write it down and wait for an opportunity (timing, network request, etc.)
- When the time comes, move the asynchronous code to the Callback Queue
- For example, when the Call Stack is empty, the Event Loop starts working
- Search the Callback Queue and move it to the Call Stack if any exists
- Keep looking around (like perpetual motion machines)
Relationship between DOM events and Event loops
$('#btn1').click(function (e) {// 1. When executing this line, temporarily store the callback function into the Web APIs
console.log('click event'); When clicked, the callback function is immediately submitted to the Callback Queue, and when the Event loop polls, the callback function is moved to the Call Stack for execution
})
Copy the code
- Asynchronous (setTimeout, Ajax, etc.) uses callbacks, based on event loops
- DOM events (not asynchronous) use callbacks, based on event loops,
DOM rendering
- When the Call Stack is idle, it attempts to render the DOM, and then the Event Loop,
- JS is single threaded and shares a thread with DOM rendering
Example: coding.imooc.com/lesson/400….
console.log('Hi');
setTimeout(() = > {
console.log('callback1');
}, 5000);
console.log('Bye');
Copy the code
Promise
This is mainly to solve the problem of callback hell
Async await: async await
- There are three states: Pending, regrettable and Rejected
- Then Return Resolved and rejected
catch
Resolved return Rejected- This is a pity (resolved) then a callback, a reject (catch
const p1 = Promise.reject("reject")
.then((data) = > {
console.log("then 1:", data);
})
.catch((error) = > {
console.log("error 1:", error);
})
.then((data) = > {
console.log("then 2:", data);
})
.catch((error) = > {
console.log("error 1:", error);
});
console.log('p1: ', p1);// fulfilled
// error 1: reject
// then 2
//
const p2 = Promise.reject('error').catch(err= > {
console.error(err)
})
console.log('p2:', p2)// fulfilled
const p3 = Promise.reject('error').catch(err= > {
throw new Error('error on catch')})console.log('p3:', p3)// rejected
Copy the code
The title
/ / the topic
// Promise.resolve().then(() => {
// console.log(1)
// }).catch(() => {
// console.log(2)
// }).then(() => {
// console.log(3)
// })
/ / 1 3
/ / the topic
// Promise.resolve().then(() => {
// console.log(1)
// throw new Error('error')
// }).catch(() => {
// console.log(2)
// }).then(() => {
// console.log(3)
// })
// // 1 2 3
Copy the code
Async /await and Promise relationship
- The async function is executed and returns a Promise object
- Await is equivalent to then of Promise
! (async function() {
const prom = Promise.reject('1')
const res = await prom// This line is not executed because await is equivalent to then, reject is not then
console.log('res', res)// This line will not be executed because an error was reported on the previous line}) ()Copy the code
async await
- Synchronous syntax, asynchronous implementation
- Await requires async wrap
- Await can be promise, async function
async function async1() {
console.log("async1 start");// This line is not asynchronous yet
await async2();
// await the callback
console.log("async1 end");
}
async function async2() {
console.log("async2");
}
console.log("script start");
setTimeout(() = > {
console.log("setTimeout");
}, 0);
async1();
new Promise((resolve) = > {
console.log("promise resolve");
resolve();
}).then(() = > {
console.log("promise then");
});
console.log("script end");
// script start
// async1 start
// async2
// promise resolve
// script end
// async1 end
// promise then
// setTimeout
Copy the code
Application scenarios of for-OF
- for… In forEach for is normal synchronous traversal
- for… Of is used for asynchronous traversal
function muti(num) {
return new Promise((resolve) = > {
setTimeout(() = > {
resolve(num * num);
}, 1000);
});
}
const nums = [1.2.3];
// nums.forEach(async (i) => {
// const res = await muti(i);
// console.log(res); // Print all at once
// });! (async function () {
for (let j of nums) {
const res = await muti(j);
console.log(res); // Print asynchronously
}
})();
Copy the code
MicroTask macroTask
- Macro task
- setTimeout
- setInterval
- Ajax
- DOM events
- Micro tasks
- Promise
- async await
- Microtasks are executed earlier than macro tasks
- The microtask fires before DOM rendering
- The macro task fires after DOM rendering
Codepen. IO/huangzonggu…
/ / 1.
// console.log("length:", document.getElementById("container").children.length);
// alert(" This Call to stack ends, DOM structure updated, but rendering has not yet been triggered ");
// 2. Microtasks before DOM rendering
Promise.resolve().then(() = > {
console.log("length:".document.getElementById("container").children.length);
alert("promise then"); // The page cannot be seen without rendering
});
//setTimeout(() => {
//console.log("length:", document.getElementById("container").children.length); / / 3
//alert("setTimout "); / / has been rendering
/ /});
Copy the code
Why microtasks execute earlier than macro tasks:
- Microtasks are defined in ES6
- Macro tasks are browser-specific
- When the Event Loop is executed, the Promise microtask is first placed in the Micro Task Queue and separated from the Callback Queue (macro task).
console.log(100);
/ / macro task
setTimeout(() = > console.log(200), 0);
Micro / / task
Promise.resolve().then(() = > console.log(300));
console.log(400);
// 100 400 300 200
Copy the code
JS-Web-API
DOM
Vue and React encapsulate DOM operations
Learn DOM with questions
- What kind of data structure is DOM
- Common apis for DOM manipulation
- Attr and property
- How to insert multiple DOM nodes at once, considering performance
knowledge
- The nature of the DOM
- The tree
- DOM node operation
-
document.createElement(name)
-
document.getElementById(id)
-
document.getElementsByTagName(name)
-
document.getElementsByClassName(className)
-
document.getElementsByTagName(tagName)
-
Document. QuerySelectorAll: returns a NodeList, IE8 + (including).
-
Document. forms: Get all the forms of the current page and return an HTMLCollection;
-
- DOM structure manipulation
- The new node
- createElement(‘p’)
- Insert the node
- AppendChild (${new key node})
- Mobile node
- AppendChild (${existing node})
- Gets the child element node
- Each node contains the nodeType attribute.
let NodeListRes = document.getElementById("div1").childNodes; console.log(NodeListRes); / / there are seven // nodeType Values: // Element node: 1 Attribute node: 2 Text node: 3 comment node: 8 NodeListRes = Array.prototype.slice .call(NodeListRes) .filter((item) = > item.nodeType === 1); console.log("filter result:", NodeListRes); Copy the code
- Gets the parent element node
document.getElementById("p2").parentNode; Copy the code
- Remove nodes
document.getElementById("div1").removeChild(document.getElementById("p3")); Copy the code
- Code demo
- The new node
- DOM performance
- DOM manipulation is performance-intensive
- Avoid frequent query and cache the query
// Frequently query DOM // for (let i = 0; i < document.getElementsByTagName("p").length; i++) { // console.log(i); // } // cache a query let tagLength = document.getElementsByTagName("p").length; for (let i = 0; i < tagLength; i++) { console.log(i); } Copy the code
- Avoid frequent operations
Attr and property
<div id='div1' class='container'>
<p>this is a p tag</p>
<p>this is a p tag</p>
<p>this is a p tag</p>
</div>
Copy the code
let pList = document.querySelectorAll("p");
// set property
pList[0].a = "a";
// set attribute
pList[1].setAttribute("a"."a");
Copy the code
- Attribute Modifies HTML attributes, which are reflected in the HTML structure
- The property changes
Custom JS properties
Is not reflected in the HTML structure- Note that style is a special case, and changing its properties will trigger changes to the DOM style that will be reflected in the DOM. Property, as we call it in everyday life, is more
Custom attributes
, for example, p1. A = 100; P1. B is equal to 200.
- Note that style is a special case, and changing its properties will trigger changes to the DOM style that will be reflected in the DOM. Property, as we call it in everyday life, is more
- Modifying attributes will lead to DOM rendering, while modifying property may lead to DOM rendering. However, it is recommended to use property as much as possible because DOM rendering will cost performance
BOM (Browser Object Model)
The title
- How to Recognize a browser
- Split the parts of the URL
knowledge
- navigator
- screen
- location
- history
Identify the browser
Navigator. userAgent is generally used to judge browsers, but this judgment is not precise, just like seeing a duck that walks and quacks like a duck. You should use the characteristics of each browser
In addition, userAgent adds a lot of markup in order for web pages to run within their own web pages.
For example, Chrome’s userAgent
Mozilla / 5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.159 Safari/537.36
/ / Opera 8.0 +
var isOpera = (!!window.opr && !! opr.addons) || !!window.opera || navigator.userAgent.indexOf(' OPR/') > =0;
/ / Firefox 1.0 +
var isFirefox = typeofInstallTrigger ! = ='undefined';
// Safari 3.0+ "[object HTMLElementConstructor]"
var isSafari = /constructor/i.test(window.HTMLElement) || (function (p) { return p.toString() === "[object SafariRemoteNotification]"; }) (!window['safari'] | | (typeofsafari ! = ='undefined' && safari.pushNotification));
// Internet Explorer 6-11
var isIE = /*@cc_on! @ * /false| |!!!!!document.documentMode;
// Edge 20+
varisEdge = ! isIE && !!window.StyleMedia;
// Chrome 1 - 71
var isChrome = !!window.chrome && (!!window.chrome.webstore || !!window.chrome.runtime);
// Blink engine detection
var isBlink = (isChrome || isOpera) && !!window.CSS;
var output = 'Detecting browsers by ducktyping:<hr>';
output += 'isFirefox: ' + isFirefox + '<br>';
output += 'isChrome: ' + isChrome + '<br>';
output += 'isSafari: ' + isSafari + '<br>';
output += 'isOpera: ' + isOpera + '<br>';
output += 'isIE: ' + isIE + '<br>';
output += 'isEdge: ' + isEdge + '<br>';
output += 'isBlink: ' + isBlink + '<br>';
document.body.innerHTML = output;
Copy the code
reference
- jsfiddle.net/6spj1059/
- Stackoverflow.com/questions/9…
Screen (window Screen)
- screen.width
- screen.height
location
console.log('href:', location.href);
console.log('protocol:', location.protocol);
console.log('host:', location.host);
console.log('hostname:', location.hostname);
console.log('hast:', location.hash);
console.log('port:', location.port);
console.log('search:', location.search);
Copy the code
history
- history.back()
- history.forwork()
- history.go(1)
The event
The title
- Write a generic event binding function
- Describe the bubbling process
- Wireless drop-down list of pictures, how to listen to each picture click
knowledge
- event
- The event bubbling
- The event agent
event
let btnElement = document.getElementById("btn");
// Normal event binding
// btnElement.addEventListener("click", () => alert("alert"));
// Generic event binding (incomplete, see compatible event broker event binding function below)
const myBind = function (type, callback, target) {
target.addEventListener(type, callback);
};
myBind("click".() = > alert("myBind"), btnElement);
Copy the code
Transform event binding
<div id='div1' class='container'>
<p id="p1">Click on me to stop bubbling</p>
<p>this is a p tag</p>
<p>this is a p tag</p>
<p>this is a p tag</p>
</div>
<div id='div2' class='container'>
<a href="#">a1</a>
<a href="#">a2</a>
<a href="#">a3</a>
<a href="#">a4</a>
<button>i am button</button>
</div>
Copy the code
/ / the bubbling
// Generic event binding: consider event brokers
const bindEvent = function (elem, eventType, selector, callback) {
if (callback == null) {
callback = selector;
selector = null;
}
elem.addEventListener(eventType, (event) = > {
console.log('event :>> ', event);
if (selector) {
// Event broker
if (event.target.matches(selector)) {
callback.call(event.target, event)// When called, this can refer to function in the callback
// callback()}}else {
// Plain binding
callback.call(event.target, event)
// callback()}}); };const bodyElem = document.body;
// const bodyElem = document.getElementById("div1");
bindEvent(bodyElem, "click".function (event) {
alert(this.innerHTML);
});
// Plain binding
const p1Elem = document.getElementById("p1");
bindEvent(p1Elem, "click".function (event) {
event.stopPropagation();// Prevent bubbling
alert(this.innerHTML);
});
// Event broker: based on bubbling event implementation
// There are too many child elements, and it can be complicated to bind the events one by one, so we can delegate the events to the parent element
const div2 = document.getElementById('div2');
// When no selector is passed, the selector itself determines whether it is the triggered target element
// bindEvent(div2, 'click', function (event) {
// event.stopPropagation();
// event.preventDefault(); // stop a tag from jumping: #
// if (event.target.nodeName === 'A') {
// console.log(' is a tag ')
// alert(this.innerHTML)
/ /}
// })
// Pass selector, modify event binding, compatible event proxy
bindEvent(div2, 'click'.'A'.function (event) {
event.stopPropagation();
event.preventDefault();// stop a tag from jumping: #
// if (event.target.nodeName === 'A') {
// console.log(' is a tag ')
alert(this.innerHTML)
// }
})
Copy the code
A: Describe the process of event bubbling
- Based on DOM tree structure
- Events bubble up the trigger element
- Application: Event broker
A: wireless drop-down list of pictures, how to listen to each picture click
- The event agent
- Use event.target to get the triggered element
- Matches checks whether the trigger is a picture
AJAX(Asynchronous JavaScript And XML)
AJAX (Asynchronous JavaScript And XML) is a programming practice for building more complex, dynamic web pages using XMLHttpRequest technology.
The target
- Write a simple AJAX (use Promise)
- No need to specify all the methods and state codes (duplicate wheel)
- Common implementations across domains
knowledge
- XMLHttpRequest
XMLHttpRequest (XHR) is a JavaScript API for creating AJAX requests. Its methods provide the ability to send requests between the browser and the server.
- Status code XMLHttpRequest. Status
Status codes are standard HTTP status codes
XMLHttpRequest.onreadystatechange
XMLHttpRequest. ReadyState: 4, to get to the response
classification | Classification description |
---|---|
0 | (uninitialized) |
1 | (load) |
2 | (Load completed) |
3 | (interaction) |
4 | The response content is parsed |
- Cross-domain: Same-origin policy, cross-domain solution
- The same origin policy of the browser
- When making an AJAX request, the browser requires that the current page and server must be of the same origin (security)
- Cognate: the protocol, domain name, and port must be the same. Agreement means the same source
- Front end: browser browsinga.com:8080/The API can only be:a.com:8080/api/xxxIf the server is not, it will be blocked by the browser
- However, the server does not intercept the data when accessing the server. As the data does not pass through the browser, the server attacks the server
- Loading images, CSS, and JS is not restricted by the same origin policy of the browser
<img SRC = cross-domain image address />
: Realize statistics through pictures and use third party statistics service<link href= cross-domain CSS address />
: the CDN<script SRC = cross-domain js address ></script>
: CDN implements JSONP
- Cross-domain (CORS: Cross-Origin Requests cross-domain resource sharing)
- All cross-domains must be allowed and coordinated by the server
- Server configuration: Access-control-allow-origin,
- All cross-domains must be allowed and coordinated by the server
- Resolve cross-domain solutions
-
Pure server
- Configure HTTP header: access-Control-allow-origin for the server
* Response. serHeader(" access-Control-allow-origin ", "http://localhost:8011"); * Response. serHeader(" access-Control-allow-origin ", "http://localhost:8011"); response.serHeader("Access-Control-Allow-Headers", "X-Requested-With"); response.serHeader("Access-Control-Allow-Origin", "PUT,POST,GET,DELETE,OPTIONS"); response.serHeader("Access-Control-Allow-Credentials", "true");Copy the code
-
The server needs to cooperate
- JSONP:JSON with Padding (填充式 JSON) (不推荐使用)
-
implementation
- Get data from script and return
Callback ({name: 'zhangsan', age: 12})Copy the code
- The front end handles script (cross-domain URL) requests for data
Function (data) {console.log(data) {// name: 'zhangsan', // age: 12}}Copy the code
-
disadvantages
- Only support the GET
- Inadequate security
- JSONP exposes a number of vulnerabilities by assuming that the code sent back is trusted, further exposing the CSRF (Cross-site request forgery) vulnerability.
- There is no error handling and debugging is difficult
-
- JSONP:JSON with Padding (填充式 JSON) (不推荐使用)
-
Pure front end
- The agent
-
- The same origin policy of the browser
Thinking 🤔
- Can you cross the method of domain, who can do a copycat taobao out? If so, then cross-domains doesn’t seem to make sense. There’s a same-origin policy constraint, but everybody knows how to get around that constraint, so there’s no constraint, right?
Some AJAX plug-ins
- jQuery
- Fetch
- Note: When an HTTP status code representing an error is received, the
fetch()
Return to the Promise ofIt’s not marked reject,Even if the HTTP status code of the response is 404 or 500. Instead, it marks the Promise state as resolve (but returns the value of resolve)ok
Property set to false), which is marked reject only when the network fails or the request is blocked.
- Note: When an HTTP status code representing an error is received, the
- axios
storage
HTTP cache
Mandatory cache
- Expires was replaced by cache-control
- Check whether the Cache expires cache-control: max-age=31536000 (in seconds)
Negotiated cache (server cache policy, judged by the server)
Etag is different from last-Modified
- Etag is preferred
- Last-modified is only accurate to the second level
- Etag(fingerprint) is more accurate if the resource is generated repeatedly without changing the content
Etag
SequenceDiagram Browser ->> Server: First Request server ->> Browser: return resource, and Etag browser ->> Server: Request Headers carries if-none-match server ->> Browser: Return 304 or return a new resource and a new Etag
Last-Modified
SequenceDiagram Browser ->> Server: Initial request server ->> Browser: Return resource, and last-Modified browser ->> Server: Again, Request Headers carries if-modified-since server ->> browser: return 304 or return a new resource and a new Etag
HTTP status code classification
classification | Classification description |
---|---|
1 * * | The server receives the request and needs the requesterContinue to Perform operations |
2 * * | successful The operation was successfully received and processed |
3 * * | redirect Further action is required to complete the request |
4 * * | Client error The request contains a syntax error or the request cannot be completed |
5 * * | Server error The server encountered an error while processing the request |