This is a 10,000-word article that systematically combs the knowledge system related to Ajax, covering almost all the knowledge points of Ajax.
Original text: louiszhai. Dead simple. IO / 2016/11/02 /…
takeaway
Asynchronous JavaScript and XML. It was first used in Internet Explorer 5 and then popularized by Mozilla, Apple, and Google. Typical examples are Outlook Web Access and GMail. Ajax is almost ubiquitous in modern web pages. Front-end and back-end separation is also based on Ajax asynchronous communication.
What do browsers do for Ajax
While almost all modern browsers support Ajax, their technical solutions fall into two categories:
① Standard browser through the XMLHttpRequest object to achieve ajax functions. It only takes a single statement to create an object to send an Ajax request.
var xhr = new XMLHttpRequest();Copy the code
② IE browser through XMLHttpRequest or ActiveXObject object also realized ajax functions.
MSXML
In view of the IE series of various “god” performance, we take a look at the Internet Explorer browser coquetty go.
The use environment of Internet Explorer is slightly complicated. Internet Explorer 7 and later browsers can directly use the XMLHttpRequest object of the BOM. IE6 and later browsers can only use ActiveXObject objects to create instances of XMLHTTPRequest objects. You need to specify a ProgID like “microsoft.xmlhttp” when you create it. In practice, on Windows, any of the following Progids should be able to create XMLHTTP objects:
Microsoft.XMLHTTP
Microsoft.XMLHTTP1.. 0
Msxml2.ServerXMLHTTP
Msxml2.ServerXMLHTTP3.. 0
Msxml2.ServerXMLHTTP4.. 0
Msxml2.ServerXMLHTTP. 5. 0
Msxml2.ServerXMLHTTP6.. 0
Msxml2.XMLHTTP
Msxml2.XMLHTTP3.. 0
Msxml2.XMLHTTP4.. 0
Msxml2.XMLHTTP. 5. 0
Msxml2.XMLHTTP6.. 0Copy the code
In short, microsoft.xmlHTTP is very old and is mainly used to provide support for legacy versions and is not recommended. For MSXML4, it has been replaced by MSXML6; MSXML5 is specifically for Office scenarios and may not be available without Microsoft Office 2003 or later installed. In contrast, MSXML6 has the advantages of being more stable, high-performance, and secure than MSXML3. It also provides some features that MSXML3 does not have, such as XSD Schema. Unfortunately, MSXML6 is only supported by default on vista systems and above; MSXML3 is available on Win2k SP4 and above. So in general, MSXML3 works as an elegant demotion to MSXML6, and we map to msxml2.xmlhttp.3.0 automatically by specifying the PorgID as msxml2.xmlhttp. As follows:
var xhr = new ActiveXObject("Msxml2.XMLHTTP");// MSXML3, equivalent to the following statement
var xhr = new ActiveXObject("MSXML2. XMLHTTP. 3.0");Copy the code
MSDN has an article dedicated to each version of MSXML. Portal: Using the right version of MSXML in Internet Explorer
IE5, IE5.5, IE6, IE7, IE8, IE9, IE10, IEEdge and other browsers can obtain the XHR object by using the following statement:
var xhr = new ActiveXObject("Msxml2.XMLHTTP");/ / MSXML3 namely
var xhr = new ActiveXObject("Microsoft.XMLHTTP");// Very old API, although browser support, the function may not be perfect, so do not recommend usingCopy the code
Above, the idea has been very clear, the following gives a fully compatible method.
Full platform-compatible XMLHttpRequest object
function getXHR(){
var xhr = null;
if(window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else if (window.ActiveXObject) {
try {
xhr = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
alert("Your browser does not support Ajax yet!"); }}}return xhr;
}Copy the code
Does Ajax break the single threaded JS mechanism
For that, let’s take a look at the browser threading mechanism. Typically, browsers have four types of threads:
- GUI rendering thread
- Javascript engine threads
- The browser event triggers the thread
- HTTP request thread
So many threads, how do they interact with the JS engine thread?
Typically, their interthread interactions take place as events, notified by event callbacks. The event callback is added to the end of the task queue in a first-in-first-out manner. When the JS engine is idle, the queued tasks in the task queue will be executed in sequence. These event callbacks include setTimeout, setInterval, Click, Ajax asynchronous request callbacks, etc.
In the browser, the JS engine thread loops fromTask queue
Read the event and execute it, a mechanism calledEvent Loop
(Event loop).
For an Ajax request, the JS engine first generates the XMLHttpRequest instance object, then calls the send method after opening it. At this point, all statements are executed synchronously. But starting from inside the SEND method, the browser creates a new HTTP request thread for the network request to occur, which is separate from the JS engine thread, and the network request is sent asynchronously. The JS engine, on the other hand, does not wait for ajax initiated HTTP requests to receive the results, but executes them sequentially.
When the Ajax request is answered by the server and the response is received, the browser event-triggering thread catches the Ajax callback event onReadyStatechange (which can also trigger onLoad, onError, and so on). The callback event is not executed immediately, but is added to the end of the task queue. Until the JS engine is idle, the tasks in the queue are fished out and executed one by one, including the onReadyStatechange event that just appends to the end of the queue.
Inside the onReadyStatechange event, it is possible to manipulate the DOM. At this point, the browser suspends the JS engine thread and executes the GUI rendering thread to repaint or reflow the UI. When the JS engine reexecutes, the GUI rendering thread is suspended again, and GUI updates are saved and executed as soon as the JS engine is idle.
Throughout the ajax request above, there are four threads that involve the browser. Except that the GUI rendering thread and JS engine thread are mutually exclusive. Other threads can execute in parallel with each other. In this way, Ajax does not break the single-threaded mechanism of JS.
Ajax and setTimeout queuing problems
In general, ajax and setTimeout event callbacks are treated equally and are automatically added to the end of the task queue in sequence, waiting to be executed when the JS engine is idle. Note, however, that not all XHR callback executions lag behind setTImeout callbacks. See the code below:
function ajax(url, method){
var xhr = getXHR();
xhr.onreadystatechange = function(){
console.log('xhr.readyState:' + this.readyState);
}
xhr.onloadstart = function(){
console.log('onloadStart');
}
xhr.onload = function(){
console.log('onload');
}
xhr.open(method, url, true);
xhr.setRequestHeader('Cache-Control'.3600);
xhr.send();
}
var timer = setTimeout(function(){
console.log('setTimeout');
},0);
ajax('https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2017/3/15/c6eacd7c2f4307f34cd45e93885d1cb6.png~tplv-t2oa ga2asx-image.image'.'GET');
console.warn('The log here was not printed first.');Copy the code
The above code execution results are shown below:
Since Ajax is asynchronous, the setTimeout callback should be executed first, but in reality, not all parts of an Ajax request are asynchronous, At least the onReadyStatechange callback for “readyState==1” and the onLoadStart callback are executed synchronously. So their output comes first.
XMLHttpRequest Attribute interpretation
Start by creating an XMLHttpRequest instance object XHR. As follows:
inherit
Try the following code.
var xhr = new XMLHttpRequest(),
i=0;
for(var key in xhr){
if(xhr.hasOwnProperty(key)){ i++; }}console.log(i);/ / 0
console.log(XMLHttpRequest.prototype.hasOwnProperty('timeout'));//trueCopy the code
As you can see, the XMLHttpRequest instance object has no own attributes. In fact, all of its attributes come from XMLHttprequest.prototype.
The XMLHttpRequest instance object has the following inheritance relationship.
xhr
<< XMLHttpRequest.prototype
<< XMLHttpRequestEventTarget.prototype
<< EventTarget.prototype
<< Object.prototype
XHR also has all the methods in archetypes such as Object. Such as the toString method.
xhr.toString();//"[object XMLHttpRequest]"Copy the code
Typically, an XHR instance object has 10 common attributes +9 methods.
readyState
Read-only property, the readyState property records all possible states during an Ajax call. Its value is straightforward as follows:
readyState | Corresponding to a constant | describe |
---|---|---|
0 (uninitialized) | xhr.UNSENT | Request established, but not initialized (the open method is not called at this time) |
1 (Initialization) | xhr.OPENED | Request established but not sent (open method called, but send method not called) |
2 (Sending data) | xhr.HEADERS_RECEIVED | Request sent (send method called, response header received) |
3 (Data transfer in progress) | xhr.LOADING | If the responseBody or responseText is not complete, then the responseBody or responseText may not be available |
4 (Done) | xhr.DONE | When the data is received, the complete response data is available via responseBody and responseText |
Note that readyState is a read-only property and it is not possible to change its value.
onreadystatechange
The onReadyStatechange event callback method fires when the readyState state changes, and the onReadyStatechange method fires four times in the course of an Ajax request cycle that receives a response. So you can bind some event callbacks to the onReadyStatechange method, such as:
xhr.onreadystatechange = function(e){
if(xhr.readystate==4) {var s = xhr.status;
if((s >= 200 && s < 300) || s == 304) {var resp = xhr.responseText;
//TODO ...}}}Copy the code
Note: The onReadyStatechange callback passes an Event instance by default, as follows:
status
Read-only property, status indicates the status of the HTTP request, with an initial value of 0. If the server does not explicitly specify a status code, status is set to the default value of 200.
statusText
Read-only property, statusText represents the server’s response status information, which is a UTF-16 string that returns an uppercase OK if the request succeeds and status==20X. Returns an empty string on request failure. Otherwise, the corresponding status description is returned. Such as: 301 Moved Permanently, 302 Found, 303 See Other, 307 Temporary Redirect, 400 Bad Request, 401 Unauthorized and so on.
onloadstart
The onLoadStart event callback method fires before the Ajax request is sent, after the readyState==1 state and before the readyState==2 state.
The onLoadStart method passes in a ProgressEvent event progress object by default. As follows:
The ProgressEvent object has three important Read only properties.
- LengthComputable specifies whether the length is computable and is a Boolean value with an initial value of false.
- Loaded indicates the size of the loaded resource. If HTTP is used to download the resource, it only indicates the size of the downloaded content, excluding HTTP headers, etc. It is an unsigned long integer with an initial value of 0.
- Total indicates the total size of the resource. If HTTP is used to download the resource, it only indicates the total size of the content, excluding HTTP headers. It is also an unsigned long integer with an initial value of 0.
onprogress
The onProgress event callback method starts when readyState==3. By default, the ProgressEvent object is passed in. The progress of loading resources can be calculated using E. loaded/ E. total.
Note: This method works with IE10+ and other modern browsers.
xhr.onprogress = function(e){
console.log('progress:', e.loaded/e.total);
}Copy the code
onload
The onload event callback method fires after the Ajax request succeeds, after the readyState==4 state.
To capture the successful status of an Ajax asynchronous request and execute the callback, the following statement is generally sufficient:
xhr.onload = function(){
var s = xhr.status;
if((s >= 200 && s < 300) || s == 304) {var resp = xhr.responseText;
//TODO ...}}Copy the code
onloadend
The onLoadEnd event callback method fires after the Ajax request completes, either after the readyState==4 state (when the response is received) or after the readyState==2 state (when no response is received).
The onLoadEnd method passes in a ProgressEvent event progress object by default.
timeout
The timeout attribute is used to specify the timeout period for Ajax. It allows you to flexibly control the upper limit of ajax request time. The value of timeout satisfies the following rules:
- Generally, 0 does not take effect.
- If the value is set to a string, the string is automatically converted to numbers. Otherwise, the value does not take effect.
- If the object can be converted to a number, it is set to the converted number.
xhr.timeout = 0; / / not to take effect
xhr.timeout = '123'; // Valid, the value is 123
xhr.timeout = '123s'; / / not to take effect
xhr.timeout = ['123']; // Valid, the value is 123
xhr.timeout = {a:123}; / / not to take effectCopy the code
ontimeout
The onTimeout method is triggered when an Ajax request times out, and it lets you do some follow-up when an Ajax request times out.
xhr.ontimeout = function(e) {
console.error("Request timeout!!")}Copy the code
response responseText
ResponseText: responseText: responseText: responseText: responseText
responseXML
The responseXML property is read-only and represents the response data in XML form. The default value is null, and an error is reported if the data is not valid XML.
responseType
ResponseType specifies the responseType. Default is an empty string (arraybuffer, blob, document, json, and text).
responseURL
ResponseURL returns the final URL of the Ajax request, and if there was a redirect in the request, the responseURL represents the URL after the redirect.
withCredentials
WithCredentials is a Boolean value. By default, it is false and indicates that no information such as cookies is sent in a cross-domain request. When it is set to true, cookies, Authorization Headers, or TLS client certificates can be sent and received normally. Obviously its value has no effect on the co-domain request.
Note: this property applies to Internet explorer 10+, opera12+ and other modern browsers.
abort
The abort method is used to cancel the Ajax request, after which the readyState state is set to 0 (UNSENT). As follows, after calling abort, the request is canceled.
getResponseHeader
The getResponseHeader method is used to get the value of the name specified in the Ajax response header. If the same name exists in Response Headers, their values are automatically concatenated as a string.
console.log(xhr.getResponseHeader('Content-Type'));//"text/html"Copy the code
getAllResponseHeaders
The getAllResponseHeaders method is used to get all safe Ajax response headers, which are returned as a string. Each HTTP header name and value are separated by colons, such as key:value, and end with \r\n.
xhr.onreadystatechange = function() {
if(this.readyState == this.HEADERS_RECEIVED) {
console.log(this.getAllResponseHeaders()); }}//Content-Type: text/html"Copy the code
Above, readyState === 2 means that the response header has been accepted as complete. At this point, you can print the complete Response headers.
setRequestHeader
Since you can get the response header, you can naturally set the request header, which is what setRequestHeader does. As follows:
// Specify a JSON format for the request type
xhr.setRequestHeader("Content-type"."application/json");
// Other headers can be set
xhr.setRequestHeader('x-requested-with'.'123456');Copy the code
onerror
The onError method is used to execute after an Ajax request fails. Usually only raised when there is a network problem or ERR_CONNECTION_RESET (OnError will also be raised under Chrome if the request returns a 407 status code).
upload
By default, the Upload attribute returns an XMLHttpRequestUpload object for uploading resources. This object has the following methods:
- onloadstart
- onprogress
- onabort
- onerror
- onload
- ontimeout
- onloadend
The above methods function the same as the methods of the same name in XHR objects. The onProgress event callback method can be used to track the progress of resource uploads.
xhr.upload.onprogress = function(e){
var percent = 100 * e.loaded / e.total |0;
console.log('upload: ' + precent + The '%');
}Copy the code
overrideMimeType
The overrideMimeType method is used to force the MIME Type of the response, that is, to force the content-type of the response. As follows, the MIME type of response returned by the server is text/plain.
xhr.getResponseHeader('Content-Type');//"text/plain"
xhr.responseXML;//nullCopy the code
Set the MIME type of response to text/ XML using the overrideMimeType method. Charset = UTF-8, as shown below:
xhr.overrideMimeType("text/xml; charset = utf-8");
xhr.send();Copy the code
The Response headers is unchanged, but the Content-Type has been replaced with the new value.
xhr.getResponseHeader('Content-Type');//"text/xml; charset = utf-8"Copy the code
At this point, xhr.responsexml will also return a DOM object, as shown below.
XHR level
When XHR1 is XMLHttpRequest Level 1.xhr1, the XHR object has the following disadvantages:
- Only text data can be transmitted. Binary data cannot be transmitted.
- When data is transferred, no progress message is displayed.
- By the browser
The same-origin policy
Restrict requests to local resources only. - The lack of a timeout mechanism makes it difficult to control the pace of Ajax requests.
XHR secondary
XHR2, XMLHttpRequest Level 2. XHR2 addresses the following shortcomings of XHR1:
- Binary data is supported, files can be uploaded, and forms can be managed using FormData objects.
- Provides progress hints that can be passed
xhr.upload.onprogress
The event callback method gets the transfer progress. - Still be
The same-origin policy
Limit, the security mechanism will not change. XHR2 new offerAccess-Control-Allow-Origin
Wait for headers, set it to*
“To allow any domain name request, thus enabling cross-domain CORS access (read on for details about CORS). - You can set timeout and ontimeout to facilitate setting the timeout duration and subsequent processing.
Here’s an example of a FormData object added to H5.
// Create FormData instance directly
var data = new FormData();
data.append("name"."louis");
xhr.send(data);
// You can also create a FormData instance by passing in the form DOM object
var form = document.getElementById('form');
var data = new FormData(form);
data.append("password"."123456");
xhr.send(data);Copy the code
Currently, most major browsers support XHR2, with the exception of the Internet Explorer family, which requires IE10 and higher. Therefore, IE10 does not support XHR2.
So what about IE7, 8, and 9 users? Unfortunately, these users are embarrassed. For IE8 and ie9, there is only a castrated version of XDomainRequest available, but IE7 does not. IE7 users will probably cry in the bathroom.
XDomainRequest
The XDomainRequest object is a toss out of IE8 and ie9 to support immature solutions to CORS requests. So much so that IT was removed from IE10 and returned to XMLHttpRequest.
XDomainRequest can only be used to send GET and POST requests. The following is the creation process.
var xdr = new XDomainRequest();Copy the code
XDR has the following properties:
- timeout
- responseText
The following methods:
- Open: Accepts only Method and URL parameters. Only asynchronous requests can be sent.
- send
- abort
The following event callbacks:
- onprogress
- ontimeout
- onerror
- onload
Except for a few missing methods, XDomainRequest is basically the same as XMLHttpRequest.
It must be made clear:
- XDomainRequest does not support cross-domain transfer of cookies.
- Only the Content-Type field of the request header can be set, and response header information cannot be accessed.
$.ajax
$. Ajax is jquery’s encapsulation of native Ajax. By encapsulating Ajax, jquery smooths out the differences between browser versions of asynchronous HTTP and replaces them with a highly uniform API. As a pioneer in the ERA of JS class libraries, jquery has had a profound impact on front-end development. It is important to know and be familiar with its Ajax approach.
The list of parameters
$.ajax() has only one argument, which sets the key-value object. In fact, all ajax requests sent by JQ are implemented by calling this Ajax method. Its detailed parameters are as follows:
The serial number | parameter | type | describe |
---|---|---|---|
1 | accepts | PlainObject | Used to inform the server of what type of return the request needs to receive. If necessary, recommend in$.ajaxSetup() Method is set once. |
2 | async | Boolean | The default is true, that is, asynchronous. |
3 | beforeSend | Function | The callback before the request is sent, with the default parameters jqXHR and Settings. An explicit return of false cancels the request. |
4 | cache | Boolean | Specifies whether to enable caching. The default value is true. If caching is not required, set it to false. However, dataType is false for “script” and “jsonp”. |
5 | complete | Function | Callback after request completion (requestsuccess 和 error JqXHR and textStatus(request status, with values of “success”,” NotModified “,”error”,”timeout”,”abort”,” parserError “). Starting with JQ1.5, Complete can be set to an array of functions. Each function will then be called in turn. |
6 | contents | PlainObject | An object paired with “{string/regular expression}” parses the return result of the request based on the given content type. |
7 | contentType | String | Encoding Type, corresponding to the “Content-Type” field in the HTTP request header field. The default is “Application /x-www-form-urlencoded; charset=UTF-8”. |
8 | context | Object | Set the context of the Ajax callback function. The default context is the parameter setting object passed in by the Ajax request. If set to document.body, all Ajax callback functions will have body as the context. |
9 | converters | PlainObject | Object of a datatype to datatype converter. The default is{"* text": window.String, "text html": true, "text json": jQuery.parseJSON, "text xml": jQuery.parseXML} . Such as settingconverters:{"json jsonp": function(msg){}} |
10 | crossDomain | Boolean | The default is false for same-domain requests and true for cross-domain requests. |
11 | data | Object, Array | Data sent to the server. By default, data is a key-value format object. If data is an array, data is usedtraditional The value of the parameter is automatically converted to a multi-valued query string with the same name. Such as {a:1,b:2} will be converted to “&a=1&b=2”. |
12 | dataFilter | Function | Handles callbacks to XMLHttpRequest’s raw response data, passing in by default data, which is the raw data returned by Ajax, and type, which is the dataType parameter provided when $. Ajax is called |
13 | dataType | String | The expected data type returned by the server can be set to one of “XML “,” HTML “,”script”,” JSON “,” JSONp “,”text”, where the data will not be processed when set to” XML “or “text”. |
14 | error | Function | The callback function if the request fails, JqXHR (native XHR object before JQ1.4),textStatus(request status, value null,”timeout”,”error”,”abort” or” parserError “),errorString(error content), When an HTTP error occurs,errorThrown Receive text parts of the HTTP status, such as “Not Found”. Starting with JQ1.5, error can be set to an array of functions. Each function will then be called in turn. Note: Error is not called for cross-domain scripts and JSONP requests. |
15 | global | Boolean | Indicates whether or not the trigger global ajax event, the default is true. Set to false will no longer trigger ajaxStart, ajaxStop, ajaxSend, ajaxError, etc. This value is automatically set to false for cross-site scripts and JSONP requests. |
16 | headers | PlainObject | Sets the request header in the format of a K-V key-value pair object. Because this setting takes effect before the beforeSend function is called, the object can be overwritten within the beforeSend function. |
17 | ifModified | Boolean | The request is allowed to succeed only if the response to the last request changes. It uses the LAST-Modified header of the HTTP package, which defaults to false. An error is reported if set to true and the data has not changed since the last request. |
18 | isLocal | Boolean | Run the current environment set to “local “, the default is false, if set to true, will affect the protocol when the request is sent. |
19 | jsonp | String | Explicitly specify the name of the callback function in the JSONP request. For example, jsonp:cb, jq will replace cb with callback, as “cb=?” Starting with JQ1.5, if jSONp :false is set, you need to explicitly set jsonpCallback:”callbackName”. |
20 | jsonpCallback | String,Function | Specify a callback function name for the JSONP request in place of the random function name automatically generated by JQ. Starting with JQ1.5, you can set this property to a function whose return value is the result of jsonpCallback. |
21 | mimeType | String | Set a MIME type to override the MIM type of XHR (new in JQ1.5) |
22 | password | String | Set the password in the authentication request |
23 | processData | Boolean | Jq’s Ajax methods by default implicitly convert incoming data into query strings (such as “&a=1&b=2”) to match the default content type “Application/X-www-form-urlencoded “, Set the transformRequest method to false if you do not want conversion. To disable the default conversion in Angular, you need to override the transformRequest method. |
24 | scriptCharset | String | Only used in “script” requests (such as cross-domain JSONP, dataType of type “script”). When explicitly specified, the request is set on the script tagcharset Property that can be used when local and remote encodings are found to be inconsistent. |
25 | statusCode | PlainObject | A set of key-value objects corresponding to HTTP status codes and callback functions. The object is represented as {404:function(){}}. Can be used to execute different callbacks based on different HTTP status codes.(added in JQ1.5) |
26 | timeout | Number | Set the timeout period. |
27 | traditional | Boolean | Whether to serialize data objects in the default way. Default is false. |
28 | type | String | This can be set to one of eight HTTP methods, and is case insensitive in JQ. |
29 | url | String | The requested URI address. |
30 | username | String | Set the user name in the authentication request |
31 | xhr | Function | Create and return an XHR object within the callback |
32 | xhrFields | PlainObject | Key value pair object, used to set native XHR objects, such as withCredentials:true(added in JQ1.5.1) |
Supporting promise
The $.ajax() method returns a jqXHR object (from jQ1.5). If you are using a non-XMLHttprequest object, such as a JSONP request, the returned jqXHR object will mimic the native XHR as much as possible. As of JQ1.5, the returned jqXHR object implements the Promise interface with the following new methods.
The new method | Old method replaced (jQ1.8 deprecated) |
---|---|
done(function(data, textStatus, jqXHR) {}) | |
fail(function(jqXHR, textStatus, errorThrown) {}) | |
always(function(data or jqXHR, textStatus, jqXHR or errorThrown) {}) |
Since JQ1.6, done, fail, always can assign multiple callbacks according to FIFO queues.
Use converter
The $.ajax() converter maps supported data types to other data types. If you need to map a custom data type to a known type. You need to use the contents option to add a conversion function between the “Content-Type” of the response and the actual data Type.
$.ajaxSetup({
contents: {
myContentType: /myContentType/
},
converters: {
"myContentType json": function(data) {
//TODO something
returnnewData; }}});Copy the code
Convert a supported type to a custom type and return. Such as text – > myContentType – > json.
$.ajaxSetup({
contents: {
myContentType: /myContentType/
},
converters: {
"text myContentType": true."myContentType json": function(data) {
//TODO something
returnnewData; }}});Copy the code
Event firing sequence
The $.Ajax () method triggers a plethora of events, as many as 20. To capture the maximum number of events, a successful upload request is used as an example, and the order in which they are invoked is as follows (the order in which the request is called in error, please correspond).
The serial number | The name of the event | Global event or not | Can it be closed | The default parameters |
---|---|---|---|---|
1 | $.ajaxPrefilter | ✔ ️ | ❌ | function(options, originalOptions, jqXHR){} |
2 | $(document).ajaxStar | ✔ ️ | ✔ ️ | Function (){}(only fired when ajax is not currently active) |
3 | beforeSend | ❌ | – | function(jqXHR, settings){} |
4 | $(document).ajaxSend | ✔ ️ | ✔ ️ | function(){} |
5 | xhr.onloadstart | – | – | ProgressEvent |
6 | xhr.upload.onloadstart | – | – | ProgressEvent |
7 | xhr.upload.onprogress | – | – | ProgressEvent |
8 | xhr.upload.onload | – | – | ProgressEvent |
9 | xhr.upload.onloadend | – | – | ProgressEvent |
10 | xhr.onprogress | – | – | ProgressEvent |
11 | xhr.onload | – | – | ProgressEvent |
12 | ❌ | – | function(data, textStatus, jqXHR){} | |
13 | $(document).ajaxSuccess | ✔ ️ | ✔ ️ | function(event, jqXHR, options){} |
14 | ❌ | – | function(jqXHR, textStatus){} | |
15 | $(document).ajaxComplete | ✔ ️ | ✔ ️ | function(event, jqXHR, textStatus) |
16 | $(document).ajaxStop | ✔ ️ | ✔ ️ | function(){} |
17 | xhr.onloadend | – | – | ProgressEvent |
As of JQ1.8, event handlers for ajaxStart, ajaxSend, ajaxSuccess, ajaxComplete, and ajaxStop can only be bound to document objects. Event handlers bound to other elements will not take effect.
Axios
In fact, if you just want a nice HTTP library, rather than the bulky jquery, the snappy Axios is probably better for you. Here’s why:
- Axios supports Node, jquery does not.
- Axios is based on the Promise syntax, which jQ3.0 only fully supports.
- Axios is shorter and more suitable for HTTP scenarios, while jquery is large and complete and loads slowly.
- Vue author Judah dropped the vue-Resource recommendation in favor of Axios. These are the words of Judah.
“Recently the team discussed that Ajax itself does not need special integration with Vue. Fetch Polyfill, Axios, superagent, etc., can achieve the same effect. Vue-resource is not worth the value it provides compared to its maintenance costs, so it has been decided to withdraw its official recommendation in the near future.”
Axios is only 12K in size and the latest version is:
Axios is syntactically basically like Promise, handling callbacks in the then method and exceptions in the catch method. As follows:
axios.get("https://api.github.com/users/louiszhai")
.then(function(response){
console.log(response);
})
.catch(function (error) {
console.log(error);
});Copy the code
In addition to GET, it supports POST, DELETE, HEAD, PUT, Patch, and Request requests. For a guide, go here: Axios.
If you need on the web page introduces Axios, can link the CDN Axios | the Bootstrap Chinese free open source project CDN service or to download it to the local.
Fetch
When it comes to Ajax, FETCH has been taken out of this article because of its length, please poke the Guide to how to advance Fetch.
Ajax cross-domain requests
What is the CORS
CORS is a W3C(World Wide Web) standard, which stands for Cross-origin Resource Sharing. It allows browsers to make asynchronous HTTP requests to cross-domain servers, overcoming the same origin policy limitations of Ajax. In fact, browsers do not block illegal cross-domain requests, but rather their responses, so many times the server will still receive the request even if it is illegal (except for HTTPS sites in Chrome and Firefox that do not allow asynchronous HTTP requests).
Typically, a cross-domain access has the following flow:
Mobile CORS compatibility
Almost all current desktop browsers (Internet Explorer 8+, Firefox 3.5+, Safari 4+, and Chrome 3+) support Ajax cross-domain calls through a protocol called cross-domain resource sharing.
What about mobile compatibility? See the picture below:
It can be seen that CORS technology has long been supported in IOS Safari7.1 and Android webview2.3. Even if the canvas of webview has problems in using cross-domain video or pictures under the earlier version, the use of CORS in mobile terminals will not be affected at all. At this point, we can rest assured that the bold application of CORS.
CORS is related to headers
1) HTTP Response Header(server provided):
-
Access-control-allow-origin: specifies which source web pages are allowed to send requests.
-
Access-control-allow-credentials: Specifies whether cookies are allowed to be sent.
-
Access-control-allow-methods: Specifies which request Methods are allowed.
-
Access-control-allow-headers: Specifies which normal header fields are allowed, such as Content-Type.
-
Access-control-expose-headers: Specifies which additional Header fields are allowed, such as X-custom-header.
This field can be omitted. By default, the xhr.getresponseHeader () method gets only six basic fields when CORS requests: Cache-control, Content-language, Content-Type, Expires, Last-Modified, Pragma. If you need to get additional fields, you need to specify them in access-Control-expose-headers. As above, xhr.getResponseHeader(‘ x-custom-header ‘) returns the value of the x-custom-header field.
-
Access-control-max-age: Specifies the validity period of the preflight OPTIONS request, in seconds.
HTTP Request Header(default browser OPTIONS Request):
- Access-control-request-method: tells the server what kind of Request the browser will send, such as POST.
- Access-control-request-headers: Tells the server what additional header fields the browser will include.
3) All the following header names are rejected:
- Accept-Charset
- Accept-Encoding
- Access-Control-Request-Headers
- Access-Control-Request-Method
- Connection
- Content-Length
- Cookie
- Cookie2
- Date
- DNT
- Expect
- Host
- Keep-Alive
- Origin
- Referer
- TE
- Trailer
- Transfer-Encoding
- Upgrade
- Via
- Contains the
Proxy-
或Sec-
Header name
CORS requests
CORS requests are divided into two types, ① simple request; ② Non-simple requests.
If the following two conditions are met, it is a simple request; otherwise, it is a non-simple request.(Part of CORS request is extracted from Teacher Ruan Yifeng’s blog)
1) The request is one of three:
- HEAD
- GET
- POST
2) HTTP header fields do not exceed the following fields:
- Accept
- Accept-Language
- Content-Language
- Last-Event-ID
- The content-type field is limited to three values
application/x-www-form-urlencoded
,multipart/form-data
,text/plain
For a simple Request, the browser sends an HTTP Request and adds an Origin field to the Request header field to identify the source of the Request. The server takes different response policies based on the source. If the server considers the request valid, add access-Control -* to the returned HTTP Response.
For non-simple requests, such as a Method POST request with a Content-Type value of Application /json or a Method PUT or DELETE request, the browser sends two HTTP requests. The first is preflight precheck (Method: OPTIONS), which mainly verifies whether the source is legitimate. Note that the OPTION request response header also needs to contain the Access-Control-* field, etc. The second time is the actual HTTP request. So the server must process the OPTIONS reply (usually a 20X status code is returned, otherwise the xhr.onerror event will be raised).
The above request flow chart is:
HTML to enable CORS
Http-equiv is the HTTP response header that gives the browser useful information to help display web content correctly and accurately. The following HTML will allow web pages under any domain name to be accessed across domains.
<meta http-equiv="Access-Control-Allow-Origin" content="*">Copy the code
CORS is enabled for images
In general, images allow cross-domain access, and you can use cross-domain images in a canvas, but doing so pollutes the canvas and makes it impossible to read its data once it is contaminated. For example, the toBlob(), toDataURL(), or getImageData() methods cannot be called. Browser this security mechanism to avoid the unauthorized remote server the picture is the risk of abuse. (this part from you enable CORS images – HTML (hypertext markup language (HTML) | MDN)
Therefore, if you want to use cross-domain image resources in your Canvas, please refer to the following Apache configuration fragment (from HTML5 Boilerplate Apache Server Configs).
<IfModule mod_setenvif.c>
<IfModule mod_headers.c>
<FilesMatch "\.(cur|gif|ico|jpe?g|png|svgz? |webp) $" >
SetEnvIf Origin ":" IS_CORS
Header set Access-Control-Allow-Origin "*" env=IS_CORS
</FilesMatch>
</IfModule>
</IfModule>Copy the code
Ajax file upload
Ajax implementation file upload is very simple, here I choose native js, jq, presents respectively to compare, and by the way, could you talk about when to use them. (ajax file upload code has been uploaded to the lot, please stamp here preview: ajax file upload demo | Louis)
1) In order to upload a file, we need to select a file first. An input box of type FILE is sufficient.
<input id="input" type="file">Copy the code
2) Then wrap the selected file at 📦 with a FormData object.
var input = document.getElementById("input"),
formData = new FormData();
formData.append("file",input.files[0]);// The key can be defined arbitrarily, as long as the background can understand itCopy the code
3) Define the URL and method for uploading. I set up a Node-webServer on Github and can clone NPM start to debug this code if necessary.
var url = "http://localhost:10108/test",
method = "POST";Copy the code
Js file upload
4.1) Encapsulate a method for sending Ajax requests.
function ajax(url, method, data){
var xhr = null;
if(window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else if (window.ActiveXObject) {
try {
xhr = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
alert("Your browser does not support Ajax yet!");
}
}
}
xhr.onerror = function(e){
console.log(e);
}
xhr.open(method, url);
try{
setTimeout(function(){
xhr.send(data);
});
}catch(e){
console.log('error:',e);
}
return xhr;
}Copy the code
4.2) Upload files and bind events.
var xhr = ajax(url, method, formData);
xhr.upload.onprogress = function(e){
console.log("upload progress:", e.loaded/e.total*100 + "%");
};
xhr.upload.onload = function(){
console.log("upload onload.");
};
xhr.onload = function(){
console.log("onload.");
}Copy the code
The upload result is as follows:
Fetch the upload
5) Fetch simply sends a POST request with the body property set to formData. Unfortunately, FETCH cannot track the progress of the upload.
fetch(url, {
method: method,
body: formData
}).then(function(res){
console.log(res);
}).catch(function(e){
console.log(e);
});Copy the code
Jquery file Upload
Jq provides a wide variety of upload plug-ins that leverage JQ’s own Ajax approach.
6) JQ’s Ajax provides XHR attributes for customizing various events.
$.ajax({
type: method,
url: url,
data: formData,
processData : false.contentType : false ,// The content-type must be false to automatically add the correct content-Type
xhr: function(){
var xhr = $.ajaxSettings.xhr();// The return new window.xmlHttprequest () object
if(xhr.upload) {
xhr.upload.addEventListener("progress".function(e){
console.log("jq upload progress:", e.loaded/e.total*100 + "%");
}, false);
xhr.upload.addEventListener("load".function(){
console.log("jq upload onload.");
});
xhr.addEventListener("load".function(){
console.log("jq onload.");
});
returnxhr; }}});Copy the code
The jQ upload result is as follows:
The jq ajax more API, please refer to the Chinese document jQuery. Ajax () | jQuery API documentation in Chinese.
Angular File upload
7.1) Angular provides the $HTTP method for sending HTTP requests, which returns a Promise object.
$http({
method: method,
url: url,
data: formData,
}).success(function(res) {
console.log(res);
}).error(function(err, status) {
console.log(err);
});Copy the code
Presents file upload code has been uploaded to the lot, please preview: stamp here presents file upload demo | Louis.
File uploads in earlier versions of Angular were not complete until Angular 1.5.5 added methods like eventHandler and uploadEventHandlers to $HTTP to support uploading progress information. As follows:
$http({
method: method,
url: url,
eventHandlers: {
progress: function(c) {// Download progress
console.log('Progress -> '+ c); }},uploadEventHandlers: {
progress: function(e) {// Upload progress
console.log('UploadProgress -> '+ e); }},data: formData,
}).success(function(res) {
console.log(res);
}).error(function(err, status) {
console.log(err);
});Copy the code
In lower versions of Angular1.5.5, refer to the mature angular-file-upload implementation and the demo Simple Example it provides.
Ajax request binaries
FileReader
The main use for binary files is H5 FileReader.
The PC supports the following:
IE | Edge | Firefox | Chrome | Safari | Opera |
---|---|---|---|---|---|
10 | 12 | 3.6 | 6 | 6 | 11.5 |
Mobile support is as follows:
IOS Safari | Opera Mini | Android Browser | Chrome/Android | UC/Android |
---|---|---|---|---|
7.1 | – | 4 | 53 | 11 |
Here’s the API:
Property/method name | describe |
---|---|
error | Represents an error that occurred while reading a file. |
readyState | Indicates the status of the read file. There are three default values :0 indicates that the file has not been loaded; 1 indicates that the file is being read. 2 indicates that the file is read successfully. |
result | The contents of the file read. |
abort() | Cancel the file read operation at this timereadyState Property will be set to 2. |
readAsArrayBuffer() | Reads a file (or BLOb object) as a typed array (ArrayBuffer), typed arrays allow developers to manipulate memory directly as array subscripts, which is very efficient because data is passed in binary form. |
Read a file (or BLOb object) as a binary string. This method has been removed from the standard API and should be used with caution. | |
readAsDataURL() | Read the file (or a blob object) as base64 encoded URL string, and the window. The URL. CreateObjectURL method effect is similar. |
readAsText() | Read the file (or BLOb object) as a text string. |
onload() | The event callback when the file has been read, passing in the event event object by default. Within this callback, either this.result or event.target.result can be used to get the contents of the file read. |
Ajax requests binary images and previews
var xhr = new XMLHttpRequest(),
url = "https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2017/3/15/c6eacd7c2f4307f34cd45e93885d1cb6.png~tplv-t2oa ga2asx-image.image";
xhr.open("GET", url);
xhr.responseType = "blob";
xhr.onload = function(){
if(this.status == 200) {var blob = this.response;
var img = document.createElement("img");
/ / a
img.src = window.URL.createObjectURL(blob);// Here the bloB still occupies memory
img.onload = function() {
window.URL.revokeObjectURL(img.src);// Free memory
};
/ / 2
/*var reader = new FileReader(); reader.readAsDataURL(blob); //FileReader will return the base64 encoded data-URI object reader.onload = function(){img.src = this.result; } * /
3 / / solution
//img.src = url; // The simplest way
document.body.appendChild(img);
}
}
xhr.send();Copy the code
Ajax requests binary text and displays it
var xhr = new XMLHttpRequest();
xhr.open("GET"."http://localhost:8080/Information/download.jsp? data=node-fetch.js");
xhr.responseType = "blob";
xhr.onload = function(){
if(this.status == 200) {var blob = this.response;
var reader = new FileReader();
reader.readAsBinaryString(blob);// This method has been removed from the standard API and reader.readastext (blob) is recommended;
reader.onload=function(){
document.body.innerHTML = "<div>" + this.result + "</div>";
}
}
}
xhr.send();Copy the code
For more information about reading binary files, check out this blog post on the new HTML5 features of files and binary data.
How do I wait for multiple Ajax requests to complete
Native JS can use Promises, which are new to ES6. ES6 Promises are based on Promises/A+ specifications (also mentioned in the Fetch Guide in this section).
A function to parse responses is provided here.
function todo(responses){
responses.forEach(function(response){
response.json().then(function(res){
console.log(res);
});
});
}Copy the code
Native JS uses the promise.all method. As follows:
var p1 = fetch("http://localhost:10108/test1"),
p2 = fetch("http://localhost:10108/test2");
Promise.all([p1, p2]).then(function(responses){
todo(responses);
//TODO do somethings
});
//"test1"
//"test2"Copy the code
Jquery can use the $.when method. This method takes one or more Deferred objects as arguments and calls the Resolved callback function only when all of them succeed, but the Rejected callback function only when one of them fails. Jq Deferred is based on Promises/A, but not exactly Promises (2).
var p1 = $.ajax("http://localhost:10108/test1"),
p2 = $.ajax("http://localhost:10108/test2");
$.when(p1, p2).then(function(res1, res2){
console.log(res1);//["test1", "success", Object]
console.log(res2);//["test2", "success", Object]
//TODO do somethings
});Copy the code
As shown above, $.when returns a jqXHR object by default, and then returns the result of the request (responseText, request status, jqXHR object).
This can be done in Angular with $q.ll (). Remember, $q needs to be injected into controller. In addition, refer to the AngularJS: ng.$q or Angular $q Service Learning Notes for $q.
var p1 = fetch("http://localhost:10108/test1"),
p2 = fetch("http://localhost:10108/test2");
$q.all([p1, p2]).then(function(responses){
todo(responses);
//TODO do somethings
});
//"test1"
//"test2"Copy the code
$q.ll () is essentially a wrapper around promise.all.
Ajax compatibility with History
One of ajax’s sore points is the inability to support browser forward and backward operations. So early Gmail used iframe to simulate ajax forward and backward.
Today, with H5 in vogue, PJAX is a combination of Ajax +history.pushState. It allows you to change page content by moving the browser forward and backward without a refresh.
Let’s look at compatibility.
IE | Edge | Firefox | Chrome | Safari | Opera | iOS Safari | Android Browser | Chrome for Android | |
---|---|---|---|---|---|---|---|---|---|
pushState/replaceState | 10 | 12 | 4 | 5 | 6 | 11.5 | 7.1 | 4.3 | 53 |
history.state | 10 | 4 | 18 | 6 | 11.5 |
IE8,9 do not use H5 history. Browsers need to use shim HTML5 history API expansion for Browsers not supporting pushState, replaceState.
pjax
Pjax is easy to use and requires only the following three apis:
- History. pushState(obj, title, URL) adds a history entry to the end of the page history, and history.length +1.
- History. replaceState(obj, title, URL) replaces the current history entry with a new one. At this point, history.length remains the same.
- Window.onpopstate is only triggered when the browser moves forward and backward (history.go(1), history.back(), and location.href=” XXX “), At this point, you get the state you just plugged in, the OBJ object, in history.state (other data types are available).
We notice that the first time we enter a page, the history.length value is 1 and history.state is empty. As follows:
1) In order to get history. State every time in the onPopState event callback, you need to automatically replace the current URL after the page is loaded.
history.replaceState("init", title, "xxx.html? state=0");Copy the code
2) Each time an Ajax request is sent, after the request is completed, the following call is made to implement the browser history forward.
history.pushState("Ajax Request parameters", title, "xxx.html? State = identifier");Copy the code
3) The popState event is automatically triggered when the browser moves forward and backward. At this point, we manually retrieve history.state, build the parameter and re-send the Ajax request or directly retrieve the state value, thus realizing the page restoration without refreshing.
window.addEventListener("popstate".function(e) {
var currentState = history.state;
//TODO concatenates the Ajax request parameters and resends the Ajax request back to the history page
//TODO or retrieve key values from state directly to restore the history page
});Copy the code
When a PopState event is triggered, the PopStateEvent event object is passed in by default. This object has the following properties.
Ajax and HTML5 history pushState/replaceState example « Zhang Xinxu – Xin Space – Xin Life
Ajax caching
HTTP caching in JS has no switch and is subject to the browser’s HTTP caching policy. In native XHR requests, caching can be turned off by setting the following.
xhr.setRequestHeader("If-Modified-Since"."0");
xhr.setRequestHeader("Cache-Control"."no-cache");
// Or the URL argument is followed by "? timestamp=" + new Date().getTime()Copy the code
You can specify cache in Settings to enable HTTP caching for jquery.
$.ajax({
url : 'url'.dataType : "xml".cache: true.// True indicates that cache is enabled. False indicates that cache is disabled
success : function(xml, status){}});Copy the code
Jquery can also set caching globally. The ajax cache is turned off globally as follows.
$.ajaxSetup({cache:false});Copy the code
In addition, browser caching during debugging is particularly nasty. You are advised to enable the privacy browser or select the Disable cache option on the ☑️ console. (Chrome is used as an example. Other browsers are similar.)
Ajax error handling
As mentioned earlier, ajax requests that receive an HTTP status code usually don’t go into error capture (except for the 407 response header in Chrome).
In fact, the $. Ajax method is slightly different in that jquery’s Ajax method also fires an error callback when type resolution fails. The most common is when the dataType is set to JSON, but the data returned is not in JSON format, and the $. Ajax error callback is emitted.
Ajax Debugging Tips
For debugging, if the interface is only making minor changes. You can use Charles (Mac) or Fiddler (Windows) as a proxy to replace the requested resource with a local file, or use its breakpoint feature to edit the response directly.
If you need to debug a new interface, you can set up the Node service locally. Configure DNS + nginx to forward HTTP requests to the local node server using the hosts file. A simple Node debugging server can be found in my Node-webServer. Here is an example of chestnut 🌰:
hosts+nginx+node-webserver
Suppose we want to debug the GET interface at www.test.com. The following steps use a Mac as an example. In other operating systems, search for 🔍 file paths.
1) Configure hosts.
sudo vim /etc/hosts
# add a new line 127.0.0.1 www.test.comCopy the code
2) nginx configuration
brew install nginx # installation
Enter the target directory after the installation is successful
cd /usr/local/etc/nginx/
cd servers The default configuration entry is nginx.conf. The *. Conf file in the Servers directory is automatically added to the configuration file list
vim test.conf
# Paste the following content
server {
listen 80;
server_name www.test.com;
index index.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
location / {
proxy_pass http://localhost:10108/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Read-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }}#:wq Save and exit
# start nginx
sudo nginx -s reload If yes, just restart it
sudo nginx If not, start itCopy the code
3) node – webServer configuration
Refer to Node-webserver. Just change index.js before starting the service and insert the following after line 9:
'get': { '/': { getKey : 'Welcome to Simple Node WebServer! '}, 'interface API ':' your response content '// insert code},Copy the code
If you need to configure CORS in Nginx, see here: Nginx implements cross-domain implementation through CORS.
Coding problem
The default character encoding for data returned by XMLHttpRequest is UTF-8, and the default character encoding for data submitted by post is UTF-8. If the page code is GBK and other Chinese code, it will produce garbled code.
Back-end interface testing techniques
Usually, if the back-end interface is OK, the front-end students need to do something to ensure that the interface is accessible.
Test the OPTIONS request using the command
curl -I -X OPTIONS -H "Origin: http://example.com" http://localhost:10108/
# responseHTTP/1.1 200 OK X-POWERed-by: Express Content-Type: text/json; charset=UTF-8 Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers: x-requested-with,Content-Type
Access-Control-Allow-Methods: GET,POST,PUT,DELETE,OPTIONS
Access-Control-Allow-Origin: http://example.com
Access-Control-Max-Age: 3600
Server: Node WebServer
Website: https://github.com/Louiszhai/node-webserver
Date: Fri, 21 Oct 2016 09:00:40 GMT
Connection: keep-alive
Transfer-Encoding: chunkedCopy the code
Above, the HTTP status code is 200, indicating that OPTIONS requests are allowed.
GET, POST requests are similar to GET, as are other requests.
curl -I -X GET -H "Origin: http://example.com" http://localhost:10108/
HTTP / 1.1 # 200 OK
curl -I -X POST -H "Origin: http://example.com" http://localhost:10108/test
HTTP / 1.1 # 200 OKCopy the code
postman
In addition, we can also test with Chrome’s Postman extension. Take a look at postman’s clean interface:
Postman supports all types of HTTP requests because it requests cookie access to Chrome and all HTTP (s) sites. Therefore, it is safe to use it for testing various web apis.
In the meantime, I strongly recommend that you upgrade your postman skills if you read this article. Here is an article about automated testing of the Postman API.
Ajax mobile compatibility
Use caution when using mobile terminals because the support is weak. Looking at his watch.
IOS Safari | Opera Mini | Android Browser | Android Chrome | Android UC | |
---|---|---|---|---|---|
XMLHttpRequest | 8.4 | – | 4.4.4 | 53 | 11(part) |
fetch | – | – | 52 | 53 | – |
This article is born for Ajax, through the introduction of XMLHTTPRequest related knowledge, and strive to be concise, this is to comb the knowledge, for readers to answer questions, but because I understand the limit, inevitably limited, I hope you are reading the essence to its dregs. thank you
That’s all for this article. If you have any questions or good ideas, please leave a comment below.
Author: Louis
This paper links: louiszhai. Making. IO / 2016/11/02 /…
Refer to the article
- XMLHttpRequest Standard
- XMLHttpRequest Level 2 User Guide – Ruan Yifeng’s network logs
- Do you really know how to use XMLHttpRequest? – Potholes on the WEB front-end – SegmentFault
- Ajax and HTML5 history pushState/replaceState example
- Cross-domain resource Sharing CORS details – Ruan Yifeng’s network log
- JQuery. Ajax () | jQuery API documentation in Chinese – jQuery Chinese website