Modern JavaScript tutorial study notes
This is my notes of learning modern JavaScript tutorials, their content is really good, there is a feeling of regret, at that time if only beginner JS can meet… No plagiarism, just notes, and try to talk about it a little bit, if involved in infringement, will be deleted immediately
Popup window
window.open(' ') // Open a popover
Copy the code
Block pop-up window
window.open() / / stop
button.onclick = () = > window.open() // Yes, popovers are user-triggered events
setTimeout(() = > window.open(), 3000) // Chrome can open popovers
Copy the code
window.open(url, name, params) //url, name: window name, params: configuration string
Copy the code
Access popup window
let newWin = window.open()
newWin.document.write(' ')
Copy the code
Visit window window.opener Visit window window.opener
Close the win.close() win.closed attribute to check whether it is closed
Win.moveby () win.moveto () win.resizeby () win.resizeto () win.onresize event for inside win.scrollby ()
win.scrollTo() elem.scrollIntoView() win.onscroll()
Window.focus () window.blur() focus/blur event
Cross-window communication
Cross-window access is restricted by same-origin not same-origin, we can’t access the content in the window, but we can modify the location
Ifame. ContentWindow Window Ifame. ContentDocument Document
<iframe src="https://example.com" id="iframe"></iframe>
<script>
iframe.onload = function() {
// We can get a reference to the inner window
let iframeWindow = iframe.contentWindow; // OK
try {
/ /... But the documents are not available
let doc = iframe.contentDocument; // ERROR
} catch(e) {
alert(e); // Security Error (another source)
}
// We cannot read the URL of the page in iframe
try {
// Cannot read the URL from the location object
let href = iframe.contentWindow.location.href; // ERROR
} catch(e) {
alert(e); // Security Error
}
/ /... We can ** write ** location (so something else is loaded in the iframe)!
iframe.contentWindow.location = '/'; // OK
iframe.onload = null; // Empty the handler and do not run it after the location changes
};
</script>
Copy the code
<script>
let oldDoc = iframe.contentDocument; / / error
iframe.onload = function() {
let newDoc = iframe.contentDocument;
// The loaded document is different from the original document!
alert(oldDoc == newDoc); // false
};
</script>
Copy the code
So in order to get the document earlier we can do this
let oldDoc = iframe.contentDocument
let timer = setInterval(() = > {
let newDoc = iframe.contentDocument
if (newDoc === oldDoc) return;
clearInterval(timer)
}, 100)
Copy the code
Frames [0] window.frames. IframeName (name=’iframeName’)
The Sandbox feature allows you to disable certain behaviors in an IFrame, and you can relax the restrictions with options
Cross-window communication
win.postMessage(data, targetOrigin) / / to win
//data data targetOrigin specifies the source of the target window
Copy the code
Received, message event
window.addEventListener('message'.function(e) {
e.data / / data
e.origin // The sender's source
e.source// To reference the sender window, reply source.postmessage ()
})
Copy the code
Clickjacking attack
We put a transparent frame with a higher Z-index on a click link, and the user clicks on it, and it falls for us
<style>
iframe { /* Iframe */ from the victim website
width: 400px;
height: 100px;
position: absolute;
top:0; left: -20px;
opacity: 0.5; Opacity :0 */
z-index: 1;
}
</style>
<div>Get rich with a click:</div>
<! -- URL from the victim site -->
<iframe src="/clickjacking/facebook.html"></iframe>
<button>Click here!</button>
<div>... You're cool (I'm actually a handsome hacker)!</div>
Copy the code
Defense:
The traditional defense
if(top ! = =window) {
top.location = window. If the location}windowIf it's not at the top, place it at the topCopy the code
Window.frames — A collection of “child” Windows (for nested iframes). Window.parent — A reference to the “parent” (external) window. Window.top — a reference to the top-level parent window.
However, it will be bypassed to prevent top-level navigation
window.onbeforeunload = function() {
return false
}
Copy the code
Ask the user if they want to leave the page, and in many cases they won’t
The sandbox feature prevents changes to top.location
X-frame-options server header X-frame-options allows or disallows pages to be displayed in frames
To display disabled functions, set a style wide 100% height100%
<style>
#protector {
height: 100%;
width: 100%;
position: absolute;
left: 0;
top: 0;
z-index: 99999999;
}
</style>
<div id="protector">
<a href="/" target="_blank">To the site</a>
</div>
<script>
// If the top-level window is from another source, an error will appear
// But in this case there is no problem
if (top.document.domain == document.domain) {
protector.remove();
}
</script>
Copy the code
Samesite Cookie Feature Cookies with the Samesite feature are only sent to a website if the website is opened directly
Browser data store
cookie
Cookie is commonly used in login. After login, the server sets a cookie, and the next request will know who is wearing the cookie
console.log(ducument.cookie)/ / display the cookie
document.cooke = ' '// Write, but only add, not replaceCookie format name = value; age=23;
Copy the code
Path path=/admin This cookie is visible under /admin/ admin/some, but not /home
Domain Domain that can access cookies Cookies in the site.com domain cannot be obtained from other.com or subdomain forum.site.com
Expires is in THE GMT format
let date = new Date(Date.now() + 86400e3)
date = date.toUTCstring()
document.cookie = "user=John; expires" + date
Copy the code
If the time is in the past, the cookie is deleted
max-age
document.cookie = "user=John; max-age=3600" // After one hour, the number of seconds from the present time, zero or negative deletion
Copy the code
secure
document.cookie = "user=John; secure" // Can be accessed only in HTTPS mode
Copy the code
Samesite avoid XSRF attack A website with a request related to another website will get another website’s cookie, which can be dangerous samesite=strict from outside the same website, cookies are never sent samesite=lax loose mode, Where the HTTP method is safe and the operation is performed with top-level navigation (not frame), then you can use lax, yuxun cookies
HttpOnly JS cannot fetch cookies or modify them; Because hackers can place JS code such as a web page and wait for the user to visit the page to launch an attack, this option can be prevented. If the website has a bug to the black tech will, hackers may get cookies through JS code will be dangerous
GDRP is the query of many foreign websites, it is a kind of law of them, they must ask the user, in order to track the user’s cookie if we want to set up a cookie with authentication session or tracking ID, then we must get the permission of the user.
LocalStorage, SessionStorage
SetItem (key, value) getItem(key) removeItem(key) Clear () Key (index) // Obtain the key name under the index length // The length of the stored content localStroage is shared in the same-origin page window
traverse
for (let i = 0; i< localStorage.length; i++) {
let key = localStorage.key(i)
}
Copy the code
SessionStorage only exists on current TAB, refresh and close None
Storage events
The above two update, triggering the event
Key — The key of the changed data (null if the.clear() method is called). OldValue — oldValue (null if new data is added). NewValue — newValue (null if data is deleted). Url – THE URL of the document where the data update occurred. StorageArea – The localStorage or sessionStorage object where the data update occurs.
Network request
Fetch can send requests, similar to Axios.
let promise = fetch(url, [options])
let response = await fetch(url)
if (response.ok) { // Status is 200-- 299, which is true
let json = await response.json() // Access the Response body as json
} else {
console.log(response.status) //status is the HTTP status code, for example, 200
}
Copy the code
Response.text () json() formData() blob() arrayBuffer()
Response Header Is a map-like header object in Response. headers
response.headers.get('Content-Type')
Copy the code
The Request header is set in fetch
let response = fetch(url, {
headers: {
Authentication: 'secret'}})Copy the code
A POST request
let response = await fecth(url, {
method: 'POST'.headers: {
'Content-Type': 'application/json; charset=utf-8'
},
body: JSON.stringfy(obj)
})
Copy the code
FormData
The FormData object represents HTML FormData
let formData = new FormData([form])
Copy the code
<form id="formElem">
<input type="text" name="name" value="John">
<input type="text" name="surname" value="Smith">
<input type="submit">
</form>
<script>
formElem.onsubmit = async (e) => {
e.preventDefault()
let response = await fetch(url, {
method: 'POST'.body: new FormData(formElem)
})
let res = await response.json()
}
</script>
Copy the code
Formdata.append (name, value) formdata.append (name, blob, Formdata.delete (name) formdata.get (name) formdata.has (name)
Formdata. set(name, value)
Tracking download progress
The Response. body attribute helps it be ReadableStream — a special object that provides the body chunk by chunk.
// Step 1: Start the fetch and get a reader
let response = await fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits?per_page=100');
const reader = response.body.getReader();
// Step 2: Get the total length (length)
const contentLength = +response.headers.get('Content-Length');
// Step 3: Read data
let receivedLength = 0; // The current number of bytes received
let chunks = []; // Array of binary blocks received (including body)
while(true) {
const {done, value} = await reader.read();
if (done) {
break;
}
chunks.push(value);
receivedLength += value.length;
console.log(`Received ${receivedLength} of ${contentLength}`)}// Step 4: Connect the block to a single Uint8Array
let chunksAll = new Uint8Array(receivedLength); / / (4.1)
let position = 0;
for(let chunk of chunks) {
chunksAll.set(chunk, position); / / (4.2)
position += chunk.length;
}
// Step 5: Decode to a string
let result = new TextDecoder("utf-8").decode(chunksAll);
// We are done!
let commits = JSON.parse(result);
alert(commits[0].author.login);
Copy the code
Termination of the fetch
The built-in object AbortController
let controller = new AbortController()
Copy the code
The controller has the method abort(), and the property signal, on which the listener abort() call is set, signal fires the abort event. Signal.aborted is true
So now set the listener on signal and call abort()
let controller = new AbortController()
let signal = controller.signal
signal.addEventListener('abort'.() = > console.log('abort'))
controller.abort()
console.log(signal.aborted)
Copy the code
Fetch works well with AbortController
let controller = new AbortController()
setTimeout(() = > controller.abort(), 1000)
try {
let response = await fetch(url, {
signal: controller.signal
})
} catch(err) {
}
Copy the code
Terminate, reject, promise
Fetch API
let promise = fetch(url, {
method: "GET".// POST, PUT, DELETE, etc.
headers: {
// The content type header value is usually set automatically
// Depends on the request body
"Content-Type": "text/plain; charset=UTF-8"
},
body: undefined // String, FormData, Blob, BufferSource, or URLSearchParams
referrer: "about:client".// or "" to not send the Referer header,
// Or the current source URL
referrerPolicy: "no-referrer-when-downgrade".// no-referrer, origin, same-origin...
mode: "cors"./ / the same - origin, no - cors
credentials: "same-origin"./ / omit, include
cache: "default".// no-store, reload, no-cache, force-cache, or only-if-cached
redirect: "follow"./ / manual, the error
integrity: "".// a hash like "sha256-abcdef1234567890"
keepalive: false.// true
signal: undefined.// AbortController to abort the request
window: window // null
});
Copy the code
Mode CORS: cross-domain request same-origin: no-cORS: simple cross-domain request
Whether the cookies and HTTP-authorization header same-origin should be sent with the request Accept-control-allow-credentials from cross-source servers are required for JavaScript to be able to access response omit: do not send, even same-origin
CORS
Two types of cross-domain request simple request and other request simple request:
- The method is GET POST HEAD
- Simple headers allow you to customize only the following headers:
Accept, accept-language, content-language, content-type is application/ x-ww-form-urlencoded, Multipart/form – data or text/plain.
When we try to send a non-simple request, the browser sends a special “preflight” request to the server — asking the server, do you accept such cross-source requests?
Also, non-simple requests are not sent unless the server explicitly acknowledges them with the header.
Cross-domain requests add an Origin header that contains the exact source, the server can check the Origin, and if it agrees to accept such a request, A special header access-Control-allow-origin is added to the response that contains either the allowed source (in our case, javascript. Info), or an asterisk *. Then the response succeeds, otherwise an error is reported.
For cross-source requests, JavaScript can only access the “simple” Response header by default:
Cache-Control Content-Language Content-Type Expires Last-Modified Pragma
To grant JavaScript Access to any other response Headers, the server must send the Access-Control-expose-headers header. It contains a comma-separated list of non-simple header names that should be made accessible. Such as
Access-Control-Expose-Headers: Content-Length,API-Key
Copy the code
For non-simple requests, it sends a “preflight” request for permission before sending such a request. The precheck Request uses the OPTIONS Method, which has no body but two headers: access-Control-request-method Header with methods that are not simple requests. Access-control-request-headers provides a comma-separated list of non-simple HTTP-headers.
If the server agrees to process the request, it will respond with a status code of 200, no body, and header:
Access-control-allow-origin must be * or the source making the request (such as javascript.info) to Allow this request. Access-control-allow-methods must have allowed Methods. Access-control-allow-headers must have a list of allowed Headers. In addition, header access-Control-max-age specifies the number of seconds to cache this permission. Therefore, the browser does not have to send prechecks for subsequent requests that satisfy a given permission.
Precheck, then the server prechecks the response, then the actual request, then the actual response
Js cross-domain requests do not carry any tie (cookies or HTTP authentication), if so, required
fetch(url, {
credentials: "include"
})
Copy the code
Fetch will send the cookie and our request to the site.
If the server agrees to accept requests with Credentials, in addition to access-Control-allow-Origin, the server should add header Access-Control-allow-credentials: true to the response. Disallow access-Control-allow-Origin to use the asterisk * for requests with credentials. As shown above, it must have an exact source
The URL object
Used to create and parse urls
let url = new URL(url, [base])
url: Full URL, or path onlybase: If the URL has only paths, the URL is generated based on baselet url1 = new URL('https://javascript.info/profile/admin');
let url2 = new URL('/profile/admin'.'https://javascript.info'); equivalentCopy the code
let url = new URL('https://javascript.info/profile/admin');
let newUrl = new URL('tester', url);
alert(newUrl); // https://javascript.info/profile/tester
let url = new URL('https://javascript.info/url');
alert(url.protocol); // https:
alert(url.host); // javascript.info
alert(url.pathname); // /url
Copy the code
SearchParams method append(name, value) — add parameter by name, delete(name) — remove parameter by name, get(name) — get parameter by name, searchParams method append(name, value) — add parameter by name, delete(name) — remove parameter by name, GetAll (name) – Gets all parameters of the same name (this is possible, for example? Set (name, value) — set/replace — sort() — sort parameters by name. … And it is iterable, similar to a Map.
The URL object is automatically encoded
If you use strings, you need to manually encode/decode special characters.
Here are the built-in functions for encoding/decoding urls:
EncodeURI – Encodes the entire URL. DecodeURI – Decoded to the state before encoding. EncodeURIComponent – Encodes URL components, such as search parameters, or hash, or pathName. DecodeURIComponent — decoded to the state before coding.
XMLHttpRequest
Fetch makes it somewhat deprecated
let xhr = new XMLHttpRequest()
xhr.open(method, URL, [async, user, password]) / / initialization
xhr.send([body]) // Send the request
// Listen for responses
xhr.onload = function() {
// Request complete, HTTp status 400 or 500, and response fully downloaded
}
xhr.oneeror = function() {
// The request cannot be issued
}
xhr.onprogress = function() {
// Trigger periodically to report how many downloads
}
Copy the code
XHR attributes: status: HTTP status code, 200, 404 statusText: HTTP status information, 200 is OK, 404 is Not found response: Response Body xhr.timeout = 1000// Timeout
Xhr. responseType sets the response format
xhr.responseType = 'json';
Copy the code
Xhr.readystate to know the current state.
UNSENT = 0; // Initial state
OPENED = 1; // Open is called
HEADERS_RECEIVED = 2; // Response header is received
LOADING = 3; // The response is being loaded (a packet is received)
DONE = 4; // Request completed
Copy the code
Readystatechange event to track them:
xhr.onreadystatechange = function() {
if (xhr.readyState === 3) {}if (xhr.readyState === 4) {}}Copy the code
Xhr.abort () terminates the request, xhr.status=0
Async false is a synchronous request. Js pauses to wait for completion and continues
The custom header
setRequestHeader(name, value)
xhr.setRequestHeader('Content-Type'.'application/json'GetResponseHeader (name) Gets the header with the given name (Set- cookies andSet-Cookie2 excepted) xhr.getresponseHeader ('Content-Type') getAllResponseHeaders() returns a divisionSet- cookies andSet- All response headers outside Cookie2.Copy the code
About POST xhr.open(‘POST’…) Use the POST method. Xhr.send (formData) sends the form to the server.
let xhr = new XMLHttpRequest()
let json = JSON.stringify({
name: "John".surname: "Smith"
});
xhr.open("POST".'/submit')
xhr.setRequestHeader('Content-Type'.'application/json')
xhr.send(json)
Copy the code
Here is another object that has no methods and is dedicated to tracking upload events: xhr.upload.
It generates events, similar to XHR, but xhr.upload fires them only when uploading:
Loadstart — Upload starts. Progress — Fires periodically during upload. Abort — Upload aborts. Error — non-HTTP errors. Load — Upload completed successfully. Timeout — Upload times out (if timeout property is set). Loadend — Upload completes, with or without success.
Cross-domain and fetch policies xhr.withCredentials = true// Can carry cookies
This is me using VUe3 ele. me, if you are interested, I hope you can have a look, thanks github.com/goddessIU/v…
Project preview address goddessiu.github. IO /