Implement the Ajax of jQuery according to the native XMLHttpRequest in JavaScript

Yun Yajun 2021-08-09 17:06:16
implement ajax jquery native xmlhttprequest


Basic introduction

XmlHttpRequest

XmlHttpRequest yes JavaScript Born in the Central Plains , A long-standing scheme for sending network requests .

Basically, all front-end frameworks complete the network request based on it .

In this chapter, we will understand its basic usage , And will achieve a connection with jQuery.ajax A network request component that functions 90 percent similar .

I haven't read it jQuery.ajax Source code , And I'm not a front-end programmer , So the following code may not be well written , Just communicate with everyone here .

Back end code

To facilitate subsequent code testing , Our backend uses Python-flask Framework to complete .

  • IP:localhost
  • PORT:5700

The code is as follows :

from logging import debug, error
from flask import Flask
from flask import request
from flask import make_response
from flask import jsonify
app = Flask(__name__)
@app.after_request # solve CORS Cross-domain request
def cors(response):
response.headers['Access-Control-Allow-Origin'] = "*"
if request.method == "OPTIONS":
# Allowed request header
response.headers["Access-Control-Allow-Headers"] = "Origin,Content-Type,Cookie,Accept,Token,authorization,user_head"
return response
@app.route("/get", methods=["get"])
def get():
user_head = request.headers.get("user_head")
user_params = request.args
print(user_params)
return jsonify(user_params, user_head)
@app.route("/post", methods=["post"])
def post():
user_head = request.headers.get("user_head")
user_params = request.form
print(user_params)
return jsonify(user_params, user_head)
@app.route("/json", methods=["post"])
def json():
user_head = request.headers.get("user_head")
user_params = request.json
return jsonify(user_params, user_head)
@app.route("/file", methods=["post"])
def file():
file_obj = request.files.get("avatar")
if file_obj is None:
return make_response(jsonify("unload avatar"), 400)
file_name = file_obj.filename
file_obj.save(file_name)
return jsonify("upload avatar success!!")
if __name__ == "__main__":
app.run(host="localhost", port=5700, debug=True)

open()

open() Method is used to create and return a request object ( Simply create , Don't send ).

Parameter interpretation :

  • method: Request mode
  • url: Request address
  • async: Asynchronous request or not

Be careful : If method by GET The way , Then we need to manually url Add parameters in

Request the relevant

send()

send() Method is used to send a network request .

Parameter interpretation :

  • body:method by POST The request body data carried during , Must be of string type

Be careful : If method by GET The way , directly xhr.send(null) that will do , because GET The request has no body

setRequestHeader()

setRequestHeader() Method is used to set the request header .

Parameter interpretation :

  • header: The request header key
  • value: The request header value

Be careful : Only one set of request header key value pairs can be set at a time , If you want to set multiple sets of request header key value pairs, call this method multiple times

abort()

abort() Method is used to cancel this network request .

Response related

getAllResponseHeaders()

getAllResponseHeaders() Method is used to get all response header data .

The returned data type is string .

getResponseHeader()

getResponseHeader() Method is used to get the specified in the response header header Of value.

The returned data type is string .

status

status Property is used to return the response of the server HTTP Response status code .

Here are some common HTTP Response status code :

  • 200: The request is successful
  • 404: request was aborted , Requested resource error
  • 500: request was aborted , An error occurred inside the server
  • 302: Redirect
  • 304: The cache is preferred

statesText

statesText Property is used to return the status text of the server response .

Such as OK、NotFound Etc .

responseText

responseText Property is used to return the body content of the response body .

The returned data type is string .

Callback function

readyState

readyState Property is used to return a status value of integer type , It indicates the current xhr The request status of the object .

share 5 Form :

  • 0: uninitialized , Not yet invoked open() Method
  • 1: Initialized , Called open() Method , But not yet called send() Method
  • 2: Has been sent , Called send() Method , But the server response has not been received yet
  • 3: Received , Some server response data has been received
  • 4: Completed , All server response data has been received

readystatechange

readystatechange Event is used to set xhr Object's readState The callback function executed when the state changes .

Easy to use

contentType explain

contentType yes HTTP A request header in the protocol , It contains the format that the browser tells the back-end server to send data this time .

It and <form> Form enctype The parameters are similar to , There are some options for common values :

Common media formats are as follows :

  • text/html : HTML Format
  • text/plain : Plain text format
  • text/xml : XML Format
  • image/gif :gif Image format
  • image/jpeg :jpg Image format
  • image/png:png Image format

With application The beginning of the media format type :

  • application/xhtml+xml :XHTML Format
  • application/xml: XML data format
  • application/atom+xml :Atom XML Aggregate format
  • application/json: JSON data format
  • application/pdf:pdf Format
  • application/msword : Word Document format
  • application/octet-stream : Binary stream data ( Such as common file downloads )
  • application/x-www-form-urlencoded : <form enctype=“”> In the default enctype,form Form data is encoded as key/value Format send to server ( Default format of data submitted by form )

Another common media format is used when uploading files :

  • multipart/form-data : When uploading files in the form , You need to use this format

We're going to use 2 One of the most popular formats to test :

  • application/x-www-form-urlencoded ( default GET and POST data format )
  • application/json( The front end needs to send JSON Format data )

GET request

send out GET request :

"use strict";
let xhr = new XMLHttpRequest();
// Bind callback function
xhr.addEventListener("readystatechange", () => {
switch (xhr.readyState) {
case 0:
console.log(" uninitialized , Not yet invoked open() Method ");
break
case 1:
console.log(" Initialized , Called open() Method , But not yet called send() Method ");
break
case 2:
console.log(" Has been sent , Called send() Method , But the server response has not been received yet ");
break
case 3:
console.log(" Received , Some server response data has been received ");
break
default:
console.log(" Completed , All server response data has been received ");
if (xhr.statusText === "OK") {
console.log(" The request is successful ");
console.log(xhr.status);
console.log(xhr.statusText);
console.log(xhr.responseText);
} else {
console.log(" request was aborted ");
console.log(xhr.status);
console.log(xhr.statusText);
console.log(xhr.responseText);
}
}
})
// Request mode , Request address and parameters , Whether to enable asynchronous submission The submitted data format is url code
xhr.open("GET", "http://localhost:5700/get?username=Jack&userage=18", true);
// Set request header , The submitted data format is url code
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8');
xhr.setRequestHeader('user_head', 'HELLO WORLD');
// Send a request
xhr.send(null);

POST request

send out POST request :

"use strict";
let xhr = new XMLHttpRequest();
// Bind callback function
xhr.addEventListener("readystatechange", () => {
switch (xhr.readyState) {
case 0:
console.log(" uninitialized , Not yet invoked open() Method ");
break
case 1:
console.log(" Initialized , Called open() Method , But not yet called send() Method ");
break
case 2:
console.log(" Has been sent , Called send() Method , But the server response has not been received yet ");
break
case 3:
console.log(" Received , Some server response data has been received ");
break
default:
console.log(" Completed , All server response data has been received ");
if (xhr.statusText === "OK") {
console.log(" The request is successful ");
console.log(xhr.status);
console.log(xhr.statusText);
console.log(xhr.responseText);
} else {
console.log(" request was aborted ");
console.log(xhr.status);
console.log(xhr.statusText);
console.log(xhr.responseText);
}
}
})
// Request mode , Request address and parameters , Whether to enable asynchronous submission
xhr.open("POST", "http://localhost:5700/post", true);
// Set request header , The submitted data format is url code
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8');
xhr.setRequestHeader('user_head', 'HELLO WORLD');
// Send a request , The submitted data format is url code
xhr.send("username=Jack&userage=18");

JSON Format

JSON Data in this format can only be represented by POST Request initiation , also contentType Should be set to appliction/json.

Examples are as follows :

"use strict";
let xhr = new XMLHttpRequest();
// Bind callback function
xhr.addEventListener("readystatechange", () => {
switch (xhr.readyState) {
case 0:
console.log(" uninitialized , Not yet invoked open() Method ");
break
case 1:
console.log(" Initialized , Called open() Method , But not yet called send() Method ");
break
case 2:
console.log(" Has been sent , Called send() Method , But the server response has not been received yet ");
break
case 3:
console.log(" Received , Some server response data has been received ");
break
default:
console.log(" Completed , All server response data has been received ");
if (xhr.statusText === "OK") {
console.log(" The request is successful ");
console.log(xhr.status);
console.log(xhr.statusText);
console.log(xhr.responseText);
} else {
console.log(" request was aborted ");
console.log(xhr.status);
console.log(xhr.statusText);
console.log(xhr.responseText);
}
}
})
// Request mode , Request address and parameters , Whether to enable asynchronous submission
xhr.open("POST", "http://localhost:5700/json", true);
// Set request header
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.setRequestHeader('user_head', 'HELLO WORLD');
// Send a request
xhr.send(JSON.stringify({ "k1": "v1", "k2": "v2" }));

understand jQuery.ajax Principle

Implementation code

Native XmlHttpRequest The method provided is too low-level , So we can encapsulate it .

Here we use jQuery Of Ajax As a blueprint , A small component that implements a similar function , It is also for the convenience of later understanding jQuery.Ajax() To prepare for .

What we're going to do :

  • To send GET request
  • To send POST request
  • It is more convenient to add request headers
  • To send JSON Request data in format
  • Implement automatic deserialization JSON Response data in format
  • File upload

The implementation is as follows :

"use strict";
class Ajax {
constructor({ url, contentType, headers, data, beforeSend, dataFilter, success, error, complete, dataType = "", processData = true, type, method = type, traditional = false }) {
// url: Address to send request ,String type
// type: How to send the request ,String type , It and method You can use
// method: How to send the request ,String type , It and type You can use
// contentType: Data encoding format , amount to form Form enctype,String type
// headers: Set the request header ,Object type
// dataType: The type of response data received , If it is json Automatically deserialize ,String type
// data: Data sent ,post The request mode is sent in the request body ,get Sending a request will add it to url after ,Object type
// processData: If true, Browser will adopt application/x-www-form-urlencoded How to code data , If false According to the incoming contentType Subject to ,bool type
// traditional: If the front end passes a Array, Such as {"k1":[1,2,3,4]} You need to add an attribute traditional:true, Otherwise, the backend will not receive the parameter .( In fact, when accepting, use request.POST.get("k1[]")) To accept , There's a problem
this.xhr = new XMLHttpRequest();
this.url = url;
this.type = (type || method).toUpperCase();
this.method = method.toUpperCase();
this.headers = headers;
this.contentType = processData && !contentType ? "application/x-www-form-urlencoded" : contentType;
this.data = data;
this.dataType = dataType.toLowerCase();
this.traditional = traditional;
// beforeSend Call before sending request , And pass in a XMLHttpRequest As a parameter .
// dataFilter After the request is successful, the call is made. . Incoming and returned data and "dataType" The value of the parameter . And must return new data ( It could have been handled ) Pass to success Callback function , In other words, it will be in success And error Previous call
// success After the request is successful, the call is made. . Incoming returned data , And the string containing the success code
// error Called on request error . Pass in XMLHttpRequest object , A string describing the error type and an exception object ( If any )
// complete Call this function when the request is completed. , Success or failure . Pass in XMLHttpRequest object , And a string containing success or error codes
this.beforeSend = beforeSend || function (xhr) { };
// By default, this function will be automatically based on dataType object responseText decode
this.dataFilter = dataFilter || function (responseText, dataType) {
switch (dataType) {
case "application/json": case "json":
// newly added ,this.xhr.responseJSON attribute
this.xhr.responseJSON = JSON.parse(responseText);
return this.xhr.responseJSON;
default:
return responseText;
}
};
this.success = success || function (responseText, statusText) { };
this.error = error || function (responseText, statusText) { };
this.complete = complete || function (xhr, statusText) { };
// Bind callback function
this.bindStateChangeEvent();
// Set the data to be sent and send
this.setRequestData();
// Set the sending mode
this.setXhrOpen();
// Set request header
this.setRequestHeader();
// Send a request
this.sendRequest();
}
bindStateChangeEvent() {
let resultText = "";
let statusText = "";
// Bind callback function , Anonymous functions are used here to make this Point to Object, otherwise this Will point to xhr
this.xhr.addEventListener("readystatechange", () => {
switch (this.xhr.readyState) {
case 1:
this.beforeSend(this.xhr);
break
case 4:
resultText = this.dataFilter(this.xhr.responseText, this.dataType || this.xhr.getResponseHeader("Content-Type").toLowerCase());
if (this.xhr.statusText === "OK") {
statusText = "success";
this.success(resultText, statusText);
} else {
statusText = "error";
this.error(this.xhr, "error");
}
this.complete(this.xhr, statusText);
break
}
});
}
setRequestData() {
// Judge whether to carry out url code , Yes 2 In this case :
// 1.contentType yes application/x-www-form-urlencoded The need when url code
// 2. The object passed in is not serialize() When the method has been serialized, you do not need url code
if (this.contentType === "application/x-www-form-urlencoded" && !Object.isFrozen(this.data)) {
this.data = this.urlEncode(this.data);
}
}
urlEncode() {
return Object.entries(this.data).reduce((prev, cur, index, array) => {
// key
let key = cur[0];
// value:2 In this case , If value It's a normal string , Go straight ahead encodeURIComponent Encoding processing , If it is an array, it will follow k1=v1&k2=v2 The way to code , And determine whether it is passed into traditional
let value = this.checkValueIsArray(cur);
if (array.length - 1 === index) {
// Judge whether it is the last , If it's the last one, add &
// traditional: If the front end passes a Array, Such as {"k1":[1,2,3,4]} You need to add an attribute traditional:true, Otherwise, the backend will not receive the parameter .( In fact, when accepting, use request.POST.get("k1[]")) To accept , There's a problem
return !this.traditional && cur[1] instanceof Array ? prev += `${key}[]=${value}` : prev += `${key}=${value}`;
} else {
return !this.traditional && cur[1] instanceof Array ? prev += `${key}[]=${value}&` : prev += `${key}=${value}&`;
}
}, "");
}
checkValueIsArray(cur) {
if (cur[1] instanceof Array) {
cur[1].forEach((value, index, array) => {
if (index != array.length - 1) {
value = encodeURIComponent(value);
array[index] = value + "&";
} else {
array[index] = String(value);
}
})
// traditional: If the front end passes a Array, Such as {"k1":[1,2,3,4]} You need to add an attribute traditional:true, Otherwise, the backend will not receive the parameter .( In fact, when accepting, use request.POST.get("k1[]")) To accept , There's a problem , Here we mainly focus on the... In the array 2 All elements starting from and after the first element are url Encoding format conversion
return this.traditional ? cur[1].join(`${cur[0]}=`) : cur[1].join(`${cur[0]}[]=`)
}
else {
return encodeURIComponent(cur[1])
}
}
setXhrOpen() {
// If the request method is GET request , It's in url After adding the code data, Otherwise, only this.url
// true The parameter is to enable asynchronous call , Is also the default option
this.xhr.open(
this.method,
this.method === "GET" ? this.url.concat("?", this.data) : this.url,
true
);
}
setRequestHeader() {
// When you don't upload files , Request header Content-Type Is a must
for (let [k, v] of Object.entries(this.headers)) {
this.xhr.setRequestHeader(k, v);
}
if (this.contentType) {
this.xhr.setRequestHeader("Content-Type", this.contentType);
}
}
sendRequest() {
// When sending a request , If the request method is GET Will use this.xhr.send(null), Otherwise... Will be used this.xhr.send(this.data)
this.xhr.send(this.method === "GET" ? null : this.data);
}
}
function getAjax(ajaxSettings) {
return new Ajax(ajaxSettings);
}
function serialize(selector) {
// The whole idea : First get an object that contains all the form items , Then the object is url code
let formNode = document.querySelector(selector);
let haveValueNodeObject = {};
Array.prototype.forEach.call(formNode.elements, (element, index, lst) => {
switch (true) {
// Multiple or single choice select Will form a list
case element.tagName === "SELECT":
Array.prototype.forEach.call(element.options, (option, index, array) => {
if (option.selected) {
haveValueNodeObject[element.name] ? haveValueNodeObject[element.name].push(option.value) : haveValueNodeObject[element.name] = [option.value];
}
})
break
// multi-select , Make up a list
case element.type === "checkbox":
if (element.checked) {
haveValueNodeObject[element.name] ? haveValueNodeObject[element.name].push(element.value) : haveValueNodeObject[element.name] = [element.value];
}
break
// The radio
case element.type === "radio":
if (element.checked) {
haveValueNodeObject[element.name] = element.value
}
break
// Other projects , Note that the file object does not get
default:
if (element.name && element.type !== "file") {
haveValueNodeObject[element.name] = element.value || "";
}
}
}
)
// Freeze objects , The representation has been serialized , Avoided when sending data url Secondary coding
// Here is to pass in an object and inherit Ajax Prototype object , Because this is the only way to use checkValueIsArray Method
return Object.freeze(Ajax.prototype.urlEncode.call(
{ data: haveValueNodeObject, traditional: true, __proto__: Ajax.prototype },
));
}
function serializeArray(selector) {
// extract form Data in form , And build it into a name:value Array of [{name:value}, {name:value}, {name:value}]
let formNode = document.querySelector(selector);
let haveValueArray = [];
Array.prototype.forEach.call(formNode.elements, (element, index, lst) => {
switch (true) {
case element.tagName === "SELECT":
Array.prototype.forEach.call(element.options, (option, index, array) => {
if (option.selected) {
haveValueArray.push({ "name": element.name, "value": option.value });
}
})
break
case element.type === "checkbox" || element.type === "radio":
if (element.checked) {
haveValueArray.push({ "name": element.name, "value": element.value });
}
break
default:
if (element.name && element.type !== "file") {
haveValueArray.push({ "name": element.name, "value": element.value });
}
}
}
)
return haveValueArray;
}
window.$ = { ajax: getAjax, serialize, serializeArray };

Supported upload formats

Because of us JavaScript The native Ajax Height according to jQuery.ajax As a blueprint . So common features should be consistent with them .

Such as the supported native upload data format :

  • Only upload is supported k-v The object of , Uploading arrays is not supported
  • In the data uploaded by the front end , Nested objects are not allowed . Such as {"k1":{"k1-1":v1}}, This will only get {“k1” : “object”}
  • If the front end passes a Array, Such as {"k1":[1, 2, 3, 4]} You need to add an attribute traditional:true, Otherwise, the backend will not receive the parameter .( In fact, when accepting, use request.POST.get("k1[]")) To accept , There's a problem

If the data you upload is json Format , Of course, these problems will not occur .

How to send GET request

send out GET An example request is as follows :

// send out GET request
$.ajax({
url: "http://localhost:5700/get",
method: "get",
headers: {
"user_head": "Hello World",
},
data: { "name": "Jack", "age": 18 },
dataType: "json",
success: (responseText, statusText) => {
console.log(responseText);
console.log(statusText);
},
error: (responseText, statusText) => {
console.log(responseText);
console.log(statusText);
},
complete: (xhr, statusText) => {
console.log(" Here you can get the response header ");
}
})

How to send POST request

send out POST An example request is as follows :

 // send out post request
$.ajax({
url: "http://localhost:5700/post",
method: "post",
headers: {
"user_head": "Hello World",
},
data: { "name": "Jack", "age": 18 },
dataType: "json",
success: (responseText, statusText) => {
console.log(responseText);
console.log(statusText);
},
error: (responseText, statusText) => {
console.log(responseText);
console.log(statusText);
},
complete: (xhr, statusText) => {
console.log(" Here you can get the response header ");
}
})

How to send JSON data

send out JSON An example of format data is as follows :

// send out json Format data
$.ajax({
url: "http://localhost:5700/json",
method: "post",
headers: {
"user_head": "Hello World",
},
data: JSON.stringify({ "name": "Jack", "age": 18 }), // 1. Manually JSON format
dataType: "json",
contentType: "application/json", // 2. The request header states that the message sent this time is JSON Format data
success: (responseText, statusText) => {
console.log(responseText);
console.log(statusText);
},
error: (responseText, statusText) => {
console.log(responseText);
console.log(statusText);
},
complete: (xhr, statusText) => {
console.log(" Here you can get the response header ");
}
})

How to submit form Data for the form

in the light of form Data submitted by form , We can use packaged 2 A function serialize() and serializeArray().

  • serialize(): extract form Data items in the form , And do url Encoding processing , Returns a string , Be careful , It does not extract the file selection box

  • serializeArray(): extract form Data in form , And build it into a name:value Array of , Be careful , It does not extract the file selection box , The final format is [{name:value}, {name:value}, {name:value}],

Examples are as follows , If it is serialize() Then submit it directly :

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form action="#" id="register">
<div>
<label for="username"> user name </label>
<input type="text" id="username" name="username" required>
</div>
<div>
<label for="password"> password </label>
<input type="password" id="password" name="password" required>
</div>
<div>
<label for="male"> male </label>
<input type="radio" name="gender" value="male" id="male" required>
<label for="female"> Woman </label>
<input type="radio" name="gender" value="female" id="female">
</div>
<div>
<label for="basketball"> Basketball </label>
<input type="checkbox" name="hobby" value="basketball" id="basketball" required>
<label for="football"> football </label>
<input type="checkbox" name="hobby" value="football" id="football">
<label for="volleyball"> Volleyball </label>
<input type="checkbox" name="hobby" value="volleyball" id="volleyball">
</div>
<div>
<label for="city"> City </label>
<select name="city" id="city" multiple>
<option value="beijing"> Beijing </option>
<option value="shanghai"> Shanghai </option>
<option value="shenzhen"> Shenzhen </option>
</select>
</div>
<div>
<label for="avatar"> Upload your avatar </label>
<input type="file" name="avatar" id="avatar">
</div>
<div>
<button type="button"> Submit </button>
</div>
</form>
</body>
<script src="./demo.js"></script>
<script>
document.querySelector("button").addEventListener("click", (event) => {
$.ajax({
url: "http://localhost:5700/post",
method: "post",
headers: {
"user_head": "Hello World",
},
data: $.serialize("#register"),
dataType: "json",
success: (responseText, statusText) => {
console.log(responseText);
console.log(statusText);
},
error: (responseText, statusText) => {
console.log(responseText);
console.log(statusText);
},
complete: (xhr, statusText) => {
console.log(" Here you can get the response header ");
}
})
console.log($.serialize("#register"));
// username=%E4%BA%91%E5%B4%96&password=123&gender=male&hobby=basketball&hobby=football&city=shanghai&city=shenzhen
})
</script>
</html>

If it is serializeArray(), Need to use appliction/json Submit in the same way , Because this method returns an array :

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form action="#" id="register">
<div>
<label for="username"> user name </label>
<input type="text" id="username" name="username" required>
</div>
<div>
<label for="password"> password </label>
<input type="password" id="password" name="password" required>
</div>
<div>
<label for="male"> male </label>
<input type="radio" name="gender" value="male" id="male" required>
<label for="female"> Woman </label>
<input type="radio" name="gender" value="female" id="female">
</div>
<div>
<label for="basketball"> Basketball </label>
<input type="checkbox" name="hobby" value="basketball" id="basketball" required>
<label for="football"> football </label>
<input type="checkbox" name="hobby" value="football" id="football">
<label for="volleyball"> Volleyball </label>
<input type="checkbox" name="hobby" value="volleyball" id="volleyball">
</div>
<div>
<label for="city"> City </label>
<select name="city" id="city" multiple>
<option value="beijing"> Beijing </option>
<option value="shanghai"> Shanghai </option>
<option value="shenzhen"> Shenzhen </option>
</select>
</div>
<div>
<label for="avatar"> Upload your avatar </label>
<input type="file" name="avatar" id="avatar">
</div>
<div>
<button type="button"> Submit </button>
</div>
</form>
</body>
<script src="./demo.js"></script>
<script>
document.querySelector("button").addEventListener("click", (event) => {
$.ajax({
url: "http://localhost:5700/json",
method: "post",
headers: {
"user_head": "Hello World",
},
data: JSON.stringify($.serializeArray("#register")), // 1. Manually JSON format
dataType: "json",
contentType: "application/json", // 2. The request header states that the message sent this time is JSON Format data
success: (responseText, statusText) => {
console.log(responseText);
console.log(statusText);
},
error: (responseText, statusText) => {
console.log(responseText);
console.log(statusText);
},
complete: (xhr, statusText) => {
console.log(" Here you can get the response header ");
}
})
console.log($.serializeArray("#register"));
// Array(7)
// 0: {username: " Yunya "}
// 1: {password: "123"}
// 2: {gender: "male"}
// 3: {hobby: "basketball"}
// 4: {hobby: "football"}
// 5: {city: "shanghai"}
// 6: {city: "shenzhen"}
})
</script>
</html>

How to upload files

If you want to send a file , We need the help of FormData Object for data submission , Here are the precautions .

  • stay <form> Upload files from the form , You have to enctype Set to multipart/form-data.

  • But in use XmlHttpRequest Object upload file , There is no need to specify contentType by multipart/form-data Format , So don't add contentType Request header .

  • contentType Should be set to false, That is, no data format is used , Do not use any encoding

  • processData Should be set to false, Don't let the browser encode any data format

Examples are as follows , We use FormData collocation serializeArray() Method to implement a real asynchronous form submission :

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form action="#" id="register">
<div>
<label for="username"> user name </label>
<input type="text" id="username" name="username" required>
</div>
<div>
<label for="password"> password </label>
<input type="password" id="password" name="password" required>
</div>
<div>
<label for="male"> male </label>
<input type="radio" name="gender" value="male" id="male" required>
<label for="female"> Woman </label>
<input type="radio" name="gender" value="female" id="female">
</div>
<div>
<label for="basketball"> Basketball </label>
<input type="checkbox" name="hobby" value="basketball" id="basketball" required>
<label for="football"> football </label>
<input type="checkbox" name="hobby" value="football" id="football">
<label for="volleyball"> Volleyball </label>
<input type="checkbox" name="hobby" value="volleyball" id="volleyball">
</div>
<div>
<label for="city"> City </label>
<select name="city" id="city" multiple>
<option value="beijing"> Beijing </option>
<option value="shanghai"> Shanghai </option>
<option value="shenzhen"> Shenzhen </option>
</select>
</div>
<div>
<label for="avatar"> Upload your avatar </label>
<input type="file" name="avatar" id="avatar">
</div>
<div>
<button type="button"> Submit </button>
</div>
</form>
</body>
<script src="./demo.js"></script>
<script>
document.querySelector("button").addEventListener("click", (event) => {
// Get the uploaded file object
let fileNode = document.querySelector("#avatar");
let fileObj = fileNode.files[0];
// Use FormData Used to forge form Data submitted by form
let fd = new FormData();
// Add files
fd.append(fileNode.name, fileObj);
// Add other form items
$.serializeArray("#register").forEach((obj, index, array) => {
fd.append(obj.name, obj.value);
});
// send out json Format data
$.ajax({
url: "http://localhost:5700/file",
method: "post",
headers: {
"user_head": "Hello World",
},
data: fd, // Direct transmission ForData Object can
dataType: "json",
contentType: false, // Must be set to false
processData: false, // Must be set to false
success: (responseText, statusText) => {
console.log(responseText);
console.log(statusText);
},
error: (xhr, statusText) => {
console.log(xhr.responseText);
console.log(statusText);
},
complete: (xhr, statusText) => {
console.log(statusText);
}
})
})
</script>
</html>
版权声明
本文为[Yun Yajun]所创,转载请带上原文链接,感谢
https://qdmana.com/2021/08/20210809165752281r.html

  1. HTML + CSS + JavaScript to achieve cool Fireworks (cloud like particle text 3D opening)
  2. HTML + CSS + JavaScript realizes 520 advertising love tree (including music), which is necessary for programmers to express themselves
  3. Solve the problem of Web front-end deployment server (it can be deployed online without a server)
  4. HTML + CSS + JS make wedding countdown web page template (520 / Tanabata Valentine's Day / programmer advertisement)
  5. What else can driverless minibus do besides "Park connection"?
  6. Cloud native leads the era of all cloud development
  7. NRM mirror source management tool
  8. Bring it to you, flex Jiugong
  9. Lolstyle UI component development practice (II) -- button group component
  10. Deconstruction assignment in ES6
  11. Luo 2 peerless Tang clan was officially launched. The official gave a key point, and the broadcast time was implied
  12. 20初识前端HTML(1)
  13. 当新零售遇上 Serverless
  14. 20 initial knowledge of front-end HTML (1)
  15. When new retail meets serverless
  16. [golang] - go into go language lesson 5 type conversion
  17. [golang] - go into go language lesson 6 conditional expression
  18. HTML5(八)——SVG 之 path 详解
  19. HTML5 (8) -- detailed explanation of SVG path
  20. 需要开通VIP以后页面内容才能复制怎么办?控制台禁用javascript即可
  21. Web前端|CSS入门教程(超详细的CSS使用讲解,适合前端初学者)
  22. 实践积累 —— 用Vue3简单写一个单行横向滚动组件
  23. Serverless 全能选手,再下一城
  24. What if you need to open a VIP to copy the page content? Just disable JavaScript on the console
  25. Web front end | CSS introductory tutorial (super detailed CSS explanation, suitable for front-end beginners)
  26. Practice accumulation - write a single line horizontal scroll component simply with vue3
  27. Dili Reba is thin again. She looks elegant and high in a strapless hollow skirt, and her "palm waist" is beautiful to a new height
  28. Serverless all-round player, next city
  29. The difference between MySQL semi synchronous replication and lossless semi synchronous replication
  30. Vue表单设计器的终极解决方案
  31. The ultimate solution for Vue form designer
  32. Nginx从理论到实践超详细笔记
  33. Yu Shuxin's red backless swimsuit is split to the waist and tail, with a concave convex figure and excessive color matching, and his face is white to dazzling
  34. Nginx ultra detailed notes from theory to practice
  35. 【动画消消乐|CSS】086.炫酷水波浪Loading过渡动画
  36. typecho全站启用https
  37. CCTV has another popular employee. The off-site interpretation is very professional, and the appearance ability is no less than that of Wang Bingbing
  38. [animation Xiaole | CSS] 086. Cool water wave loading transition animation
  39. Enable HTTPS in Typecho
  40. 50天用JavaScript完成50个web项目,我学到了什么?
  41. 根据JavaScript中原生的XMLHttpRequest实现jQuery的Ajax
  42. What have I learned from completing 50 web projects with JavaScript in 50 days?
  43. "My neighbor doesn't grow up" has hit the whole network. There are countless horse music circles, and actor Zhou Xiaochuan has successfully made a circle
  44. 根据JavaScript中原生的XMLHttpRequest实现jQuery的Ajax
  45. Implement the Ajax of jQuery according to the native XMLHttpRequest in JavaScript
  46. Implement the Ajax of jQuery according to the native XMLHttpRequest in JavaScript
  47. 30 + women still wear less T-shirts and jeans. If they wear them like stars, they will lose weight
  48. 数栈技术分享前端篇:TS,看你哪里逃~
  49. Several stack technology sharing front end: TS, see where you escape~
  50. 舍弃Kong和Nginx,Apache APISIX 在趣链科技 BaaS 平台的落地实践
  51. Abandon the landing practice of Kong and nginx, Apache apisik on the baas platform of fun chain technology
  52. 浪迹天涯king教你用elementui做复杂的表格,去处理报表数据(合并表头,合并表体行和列)
  53. 前端HTML两万字图文大总结,快来看看你会多少!【️熬夜整理&建议收藏️】
  54. Wandering around the world king teaches you to use elementui to make complex tables and process report data (merge header, merge table body rows and columns)
  55. 路由刷新数据丢失 - vuex数据读取的问题
  56. Front end HTML 20000 word graphic summary, come and see how much you can【 Stay up late to sort out & suggestions]
  57. Route refresh data loss - vuex data reading problem
  58. Systemctl系统启动Nginx服务脚本
  59. Systemctl system startup nginx service script
  60. sleepless