AJAX
An overview,
background
- When the user login function is enabled, the user’s profile picture cannot be displayed when the user enters an email address
- Unable to implement user registration function, when the user enters a mailbox or user name prompt whether there is
- The latest user messages cannot be viewed in real time when the message board function is implemented
Before that, we can make the browser make a request to the server to get the server data in the following ways:
- Address bar to enter the address, press Enter, refresh
- Href or SRC attribute for a particular element
- The form submission
These are all scenarios that we cannot or cannot program in code (making a request to the server and receiving the response from the server)
A technical solution for web programming (sending requests and receiving responses) on the browser side, which allows us to get the latest content from the server directly through JavaScript without having to reload the page. Make the Web more similar to the desktop application user experience.
Summary of Application Scenarios
For every unknown technology, when we learn about it, our first reaction is under what circumstances?
- Get data on demand
- Verify user data
- Automatically updates page content
- Improve user experience, no refresh experience
Second, get started quickly
At the core of the AJAX API is an XMLHttpRequest type that all AJAX operations need to use.
The process of using AJAX can be analogous to how we normally visit a web page
1. Create an object of type XMLHttpRequest -- equivalent to opening a browser
var xhr = new XMLHttpRequest()
// 2. Open a connection to a url -- equivalent to entering the address in the address bar
xhr.open('GET'.'/time')
// 3. Send a request over the connection -- equivalent to enter or click access to send the request
xhr.send(null)
// 4. Specify the XHR state change event handler -- the equivalent of handling the rendered web page
xhr.onreadystatechange = function () {
// XHR's readyState determines whether the response to this request is received
if (this.readyState === 4) {
// Get the response body of the response from XHR's responseText
console.log(this.responseText)
}
}
Copy the code
readyState
var xhr = new XMLHttpRequest()
console.log(xhr.readyState)
/ / = > 0
// Initializes the request proxy object
xhr.open('GET'.'/time')
console.log(xhr.readyState)
/ / = > 1
The open method has been called to establish a connection to a specific port on the server
xhr.send()
xhr.addEventListener('readystatechange'.function () {
switch (this.readyState) {
case 2:
/ / = > 2
// The response header has been received
// Can get the head
// console.log(this.getAllResponseHeaders())
console.log(this.getResponseHeader('server'))
// But I haven't got the body yet
console.log(this.responseText)
break
case 3:
/ / = > 3
// The response body of the response packet is being downloaded. The response body may be empty or incomplete
// The response body is not safe to handle here.
console.log(this.responseText)
break
case 4:
/ / = > 4
// All is OK (the entire response message has been downloaded completely)
// The response body is processed here
console.log(this.responseText)
break}})Copy the code
Understanding the meaning of each state value leads to the conclusion that we generally execute the subsequent logic of the response when readyState is 4.
xhr.onreadystatechange = function () {
if (this.readyState === 4) {
// Subsequent logic......}}Copy the code
Follow the HTTP
XMLHttpRequest is essentially JavaScript’s way of sending HTTP requests in the Web platform, so the request we send is still an HTTP request, which also conforms to HTTP conventions:
// Sets the request line for the request message
xhr.open('GET'.'/time')
// Set the request header
xhr.setRequestHeader('Accept'.'text/plain')
// Set the request body
xhr.send(null)
xhr.onreadystatechange = function () {
if (this.readyState === 4) {
// Get the response status code
console.log(this.status)
// Get the response status description
console.log(this.statusText)
// Get the response header information
console.log(this.getResponseHeader('Content-Type')) // Specify the response header
console.log(this.getAllResponseHeaders()) // All response headers
// Get the response body
console.log(this.responseText) // In text form
console.log(this.responseXML) // it is in XML format}}Copy the code
Reference links:
- Developer.mozilla.org/zh-CN/docs/…
- Developer.mozilla.org/zh-CN/docs/…
The specific use
A GET request
Usually during a GET request, parameters are passed through the? Parameter passing.
var xhr = new XMLHttpRequest()
// GET requests usually pass parameters using question marks
// We can pass data to the server by adding parameters to the request address
xhr.open('GET'.'/delete? id=1')
// Generally, there is no need to set the response body for GET requests. You can pass NULL or no response at all
xhr.send(null)
xhr.onreadystatechange = function () {
if (this.readyState === 4) {
console.log(this.responseText)
}
}
// In general, URLS pass parameter data, while POST is usually business data
Copy the code
A POST request
During POST request, the request body is used to carry the data to be submitted.
var xhr = new XMLHttpRequest()
The first argument to the open method sets the request method
xhr.open('POST'.'/add')
// Set the content-type in the request header to Application /x-www-form-urlencoded
// The request size for the request is urlencoded for the server to receive data
xhr.setRequestHeader('Content-Type'.'application/x-www-form-urlencoded')
// Data that needs to be sent to the server can be sent as an argument to the send method
// Format: name=zhangsan&age=18
xhr.send('name=zhangsan&age=18')
xhr.onreadystatechange = function () {
if (this.readyState === 4) {
console.log(this.responseText)
}
}
Copy the code
Synchronous and asynchronous
The third parameter to the xhr.open() method requires a bool that sets whether the request is executed asynchronously or not. The default value is true, and false can be passed if the request is executed synchronously:
console.log('before ajax')
var xhr = new XMLHttpRequest()
// The default third argument is true, which means that the execution is asynchronous
xhr.open('GET'.'/time'.true)
xhr.send(null)
xhr.onreadystatechange = function () {
if (this.readyState === 4) {
// The code here is executed last
console.log('request done')}}console.log('after ajax')
Copy the code
If executed synchronously, the code gets stuck in xhr.send() :
console.log('before ajax')
var xhr = new XMLHttpRequest()
// Synchronization mode
xhr.open('GET'.'/time'.false)
// // Synchronously registers events before invoking Send. Otherwise, readyStatechange cannot be triggered
// xhr.onreadystatechange = function () {
// if (this.readyState === 4) {
// // The code here is executed last
// console.log('request done')
/ /}
// }
xhr.send(null)
// The response has been downloaded because the send method has been executed
console.log(xhr.responseText)
console.log('after ajax')
Copy the code
The XMLHttpRequest API to summarize
attribute
readyState
XHR status 4 The response body is receivedstatus
Get status coderesponseText
Gets the response body in text formatresponseXML
Gets the response body in XML formatonreadystatechange
Event that is emitted when the xhr.readyState property changes
methods
open(method, url, async)
Set request mode, request path, synchronous false/ asynchronous truesend(requsetBody)
Send a request (body)setRequestHeader(key, value)
Set the request headergetResponseHeader(key)
Get the response header
Response data format
Question: What if I want the server to return complex data?
The question is what format the server sends the data in, and how that format is parsed in JavaScript on the client side.
The cache problem
Caching is a problem where multiple AJAX GET requests to the same URL GET the same result. Most browsers don’t have this problem anymore, except for the early Days of Internet Explorer
var xhr = new XMLHttpRequest()
xhr.open('GET'.'/time')
xhr.send(null)
xhr.onreadystatechange = function () {
if (this.readyState ! = =4) return
console.log(this.responseText)
// => Get the same result every time
}
Copy the code
The solution
URL with time stamp
The trick is to make the browser think the address is different every time it requests it.
var xhr = new XMLHttpRequest()
xhr.open('GET'.'/time? t=' + Date.now())
xhr.send(null)
xhr.onreadystatechange = function () {
if (this.readyState ! = =4) return
console.log(this.responseText)
/ / = >
}
Copy the code
The server sets the response header
The server tells the client browser not to cache the current address through the response header in the HTTP response packet.
app.get('/time'.(req, res) = > {
res.setHeader('Cache-Control'.'no-cache')
res.setHeader('Pragma'.'no-cache')
res.setHeader('Expires'.'1')
res.send(Date.now().toString())
})
Copy the code
More often than not, this problem is solved by stamping in front end development, because it is controllable in front end.
Compatible with the plan
XMLHttpRequest has compatibility issues in older browsers (IE5/6) and can be replaced in another way.
var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP')
// XHR has the same members
Copy the code
Three, encapsulation
AJAX request encapsulation
/** * Send an AJAX request *@param {String} Url Request address *@param {String} Method Request method *@param {Object} Params request parameter *@param {Function} Done What needs to be done after the request completes (delegate/callback) */
function ajax (url, method, params, done) {
// Convert to uppercase for subsequent judgment
method = method.toUpperCase()
// Object format parameters are converted to urlencoded format
var pairs = []
for (var key in params) {
pairs.push(key + '=' + params[key])
}
var querystring = pairs.join('&')
var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP')
xhr.addEventListener('readystatechange'.function () {
if (this.readyState ! = =4) return
// Try to parse the response body in JSON format
try {
done(JSON.parse(this.responseText))
} catch (e) {
done(this.responseText)
}
})
// If it is a GET request, set the URL question mark parameter
if (method === 'GET') {
url += '? ' + querystring
}
xhr.open(method, url)
// If it is a POST request, set the request body
var data = null
if (method === 'POST') {
xhr.setRequestHeader('Content-Type'.'application/x-www-form-urlencoded')
data = querystring
}
xhr.send(data)
}
ajax('get'.'/getsomthing', { id: 123 }, function (data) {
console.log(data)
})
ajax('post'.'/addsomthing', { foo: 'posted data' }, function (data) {
console.log(data)
})
Copy the code
In the jQuery AJAX
JQuery has an Ajax-specific package that you need to pay attention to when you use it frequently.
Reference:
- www.jquery123.com/category/aj…
- www.w3school.com.cn/jquery/jque…
$.ajax
$.ajax({
url: '/time'.type: 'get'.dataType: 'json'.data: { id: 1 },
beforeSend: function (xhr) {
console.log('before send')},success: function (data) {
console.log(data)
},
error: function (xhr) {
console.log(xhr)
},
complete: function (xhr) {
console.log('request completed')}})Copy the code
Common options:
- Url: request address
- Type: request method, default
get
- DataType: dataType of server response
- ContentType: request body contentType, default
application/x-www-form-urlencoded
- Data: Data that needs to be passed to the server, via the URL if GET or the request body if POST
- Timeout: request timeout period
- BeforeSend: Triggered before the request is initiated
- Success: Triggered after the request is successful (response status code 200)
- Error: The request fails
- Complete: the request is triggered (whether successful or not)
$.get
GET Request shortcut
$.get(url, data, callback)
Copy the code
$.post
POST request shortcut
$.post(url, data, callback)
Copy the code
Global event handling
www.jquery123.com/category/aj…
Axios
Axios is the most widely used AJAX packaging library at present. Compared with jQuery, Axios has more powerful functions and more simple responsibilities, which will be specially introduced in the later stage.
axios.get('/time')
.then(function (res) {
console.log(res.data)
})
.catch(function (err) {
console.error(err)
})
Copy the code
Fourth, the XMLHttpRequest 2.0
HTML5 to the XMLHttpRequest type comprehensive upgrade, easier to use, more powerful
The response properties
onload / onprogress
var xhr = new XMLHttpRequest()
xhr.open('GET'.'/time')
xhr.onload = function () {
// onload readyState => 4
// Only when the request completes
console.log(this.readyState)
}
xhr.onprogress = function () {
// onprogress readyState => 3
// Only when the request is in progress
console.log(this.readyState)
}
xhr.send(null)
Copy the code
FormData
AJAX operations that previously could only submit strings can now submit binary data
Download binary data using XMLHTTPRequest
var xhr = new XMLHTTPRequest();
xhr.open("GET", url, true);
/ / set the responseType
xhr.responseType = 'arraybuffer';
xhr.addEventListener('load'.function() {
if(xhr.status === 200) {
console.log(xhr.response); // ArrayBuffer
console.log(new Blob([xhr.response])); // Blob
}
})
xhr.send();
Copy the code
Download using JQuery Ajax
Ajax does not support arrayBuffer or BLOB as its dataType. So we need to write a beforeSend handler:
// Ajax setup function
$.ajaxSetup({
beforeSend: function(jqXHR, settings) {
if(settings.dataType === 'binary') {
settings.xhr().responseType = 'arraybuffer';
settings.processData = false;
}
}
})
$.ajax({
url: url,
dataType: 'binary'.success: function(data) {
console.log(data); // ArrayBuffer
console.log(new Blob([data])); // Blob}})Copy the code
Upload a binary file
// Monitor progress API
xhr.upload.onload = function() {
taskPanel.style.display = 'none';
}
xhr.upload.onloadstart = function() {
taskPanel.style.display = 'block';
}
xhr.upload.onprogress = function(e) {
// Continuously triggered during upload
// console.log(e);
taskProgressStatusdiv.innerHTML = (e.loaded / e.total).toFixed(2) + The '%';
progressDiv.style.width = (e.loaded / e.total) + The '%';
}
// The body of the request needs to be passed in as an argument to the send method
// xhr.send('a=1&b=2');
// formData: formData can be built from the built-in formData object in JS
// https://developer.mozilla.org/zh-CN/docs/Web/API/FormData
let fd = new FormData();
// fd.append('a', 1);
// fd.append('b', 2);
fd.append('attachment', fileElement.files[0]);
xhr.send(fd);
Copy the code
The pros and cons of Ajax
Ajax advantages
-
The asynchronous mode improves user experience
-
Optimized transfer between browser and server to reduce unnecessary data round-trip and reduce bandwidth usage
-
Ajax runs on the client side, taking over some of the work that would have been done by the server, reducing the load on the server under a large number of users.
-
Ajax can achieve asynchronous communication effect, realize local page refresh, bring better user experience; Obtain data on demand to save bandwidth resources.
Ajax shortcomings
-
Ajax does not support the browser back button, so it costs a lot to implement the front and back functions under Ajax. May cause an increase in the number of requests cross-domain problem limits
-
Security issues AJAX exposes the details of the server interaction.
-
Search engine support is weak.
-
Broke the exception mechanism of the program.
Get and POST
Get is generally used for query operations. The URL address has a limited length and the requested parameters are exposed in the URL address. If Chinese parameters are transmitted, they need to be encoded by themselves, resulting in low security.
The POST request is used to submit data without any restriction on the length of the data. The submitted data is stored in the HTTP request body and will not be leaked in the URL address.