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>