Introduction
If you are ambiguous about the request, or know which request libraries are available, but you are only proficient in one or two of them, you don’t know all of them. Come on, this article is very suitable for you.
This article explains a change in the request library in the history of front-end development, from the beginning Ajax
, to the later jQuery Ajax
, and then fetch
, and then axios
. The author will introduce the use of each request library in detail, as well as the pitfalls. Finally, their respective advantages and disadvantages are summarized. I believe that after reading this article, you will gain something. Friends are also welcome to like and collect, I believe you will use it later.
The request interface of all the examples in this article is at the end of the article, using node + express to build
Before talking about the request library, let's recall the form first.
form
In most cases, the data or pictures or multimedia effects displayed on the webpage are static data, but sometimes the user needs to perform dynamic data interaction with the server through the webpage, such as login, registration and other operations, and a form is needed at this time.
The form is actually composed of elements such as input boxes, radios, check boxes, etc. When the user clicks the submit button, the browser will send the data to the URL set in the form. After the server corresponding to the URL receives and processes the data, it will send the data to returned to the browser.
form submission
There are generally two ways to submit a form:
The first is to use type
the submit
button for submit.
The second is to get the form and then manually call submit()
the method to submit it.
submit button to submit
<h3>form1 直接提交</h3>
<form action="http://localhost:3000/test" onsubmit="submit1()">
<input type="text" name="name" placeholder="请输入名字" />
<input type="number" name="age" placeholder="请输入年龄" />
<input type="submit" />
</form>
The page is rendered as follows, click type="submit"
the submit button to submit our form. After submission, the method corresponding to our onsubmit
attribute will be automatically triggered, here is submit1
the method that will be triggered.
Manually call the submit method to submit
<h3>form2 手动提交</h3>
<form action="http://localhost:3000/test" id="form2" onsubmit="submit1()">
<input type="text" name="name" placeholder="请输入名字" />
<input type="number" name="age" placeholder="请输入年龄" />
<!-- 这个按钮可以放在表单内也可以放在表单外 -->
<input type="button" id="submitBtn2" value="提交" onclick="handleSubmit()"/>
</form>
In js
it, we can also get the form in the event of the button, and then call submit()
the method of the form to submit the form.
handleSubmit = function () {
const form2 = document.getElementById("form2");
form2.submit();
};
The page rendering is as follows, click the submit button, and then manually submit()
submit our form through the method. Note that this method will not trigger onsubmit
the method corresponding to the attribute.
Here we are button
directly binding the click event, of course, you can also process it by obtaining button
and binding the event.button
// 方式1
const submitBtn2 = document.getElementById("submitBtn2");
submitBtn2.onclick = function () {
const form2 = document.getElementById("form2");
form2.submit();
};
// 方式2
const submitBtn2 = document.getElementById("submitBtn2");
submitBtn2.addEventListener("click", function () {
const form2 = document.getElementById("form2");
form2.submit();
});
Because the page is refreshed every time the form is submitted , the experience is not very good, so it came out later Ajax
. Ajax
It is a technology that can update some web pages without reloading the entire web page. In order to make the request smoothly later Ajax
, we must prevent the behavior of page jump by default after the form is submitted. So let's take a look at the ways to prevent form submissions?
prevent form submission
There are generally three ways to prevent form submission:
The first is onsubmit
to return to the bound method false
to prevent form submission.
The second is to return the submit button false
to prevent form submission.
The third is to block the default behavior of the submit button to prevent form submission.
onsubmit returns false
Let's look at the first
<form action="http://localhost:3000/test" onsubmit="return submit1()">
<input type="text" name="name" placeholder="请输入名字" />
<input type="number" name="age" placeholder="请输入年龄" />
<input type="submit" id="submitBtn1" />
</form>
Returning in onsubmit
the corresponding method false
can prevent the form submission
function submit1() {
return false;
}
Submit button returns false
<form action="http://localhost:3000/test">
<input type="text" name="name" placeholder="请输入名字" />
<input type="number" name="age" placeholder="请输入年龄" />
<input type="submit" id="submitBtn2" onclick="return handleSubmit()" />
</form>
false
Just return in the method corresponding to the submit button . Similar to the above.
function handleSubmit() {
return false;
}
Of course, you can also use the method of binding events
<form action="http://localhost:3000/test">
<input type="text" name="name" placeholder="请输入名字" />
<input type="number" name="age" placeholder="请输入年龄" />
<input type="submit" id="submitBtn2" />
</form>
false
You can also prevent the form from submitting by binding an event to the submit button and returning in the event . Note that it is invalidaddEventListener
to return in this way of binding events .false
const submitBtn2 = document.getElementById("submitBtn2");
submitBtn2.onclick = function () {
return false;
};
// 无效 无 效无效 无效
const submitBtn2 = document.getElementById("submitBtn2");
submitBtn2.addEventListener("click", function () {
return false;
});
prevent submit button default behavior
We can also block the default event of the submit button to prevent form submission.
<form action="http://localhost:3000/test">
<input type="text" name="name" placeholder="请输入名字" />
<input type="number" name="age" placeholder="请输入年龄" />
<input type="submit" id="submitBtn2" onclick="handleSubmit()" />
</form>
preventDefault
Use the blocking default event in the method corresponding to the submit button .
// 这种方式需要window.event来获取事件对象
function handleSubmit(e) {
const event = e || window.event;
event.preventDefault();
}
Of course, you can also use the method of binding events
<form action="http://localhost:3000/test">
<input type="text" name="name" placeholder="请输入名字" />
<input type="number" name="age" placeholder="请输入年龄" />
<input type="submit" id="submitBtn2" />
</form>
preventDefault
By binding the event to the submit button, and then using the blocking default event in the event .
// 方式1
const submitBtn2 = document.getElementById("submitBtn2");
submitBtn2.onclick = function (e) {
e.preventDefault();
};
// 方式2
const submitBtn2 = document.getElementById("submitBtn2");
submitBtn2.addEventListener("click", function (e) {
e.preventDefault();
});
After talking about the submission of the form, let's talk about another very important knowledge point of the formenctype
enctype attribute
enctype
It is used to define how to encode the data when the form data is submitted to the server. The optional values are:
- application/x-www-form-urlencoded;
- multipart/form-data;
- text/plain
application/x-www-form-urlencoded
The default method is the first one application/x-www-form-urlencoded
. When submitting data using the form form, it will be converted into key=value&key=value
data in this format by default.
For the request, such a link get
will be generated from the form parameters , and the request will be made after the current link. For the request, the form parameters will be generated into such a link, and placed in the request body for the request.?key=value&key=value
action
post
key=value&key=value
And some characters (Chinese, special characters, etc.) in the parameters will be encoded.
Why edit the submitted data?
When using the form form to submit data, the data needs to be encoded, because the data of the URL is transmitted to the server ?key=value&key=value&
through , which has some special characters as functional properties. For example & ? =
, if the data contains these characters and is not encoded , which may cause errors in the transmitted data. For example, ?key=value
if the value 123&456
is originally, then the value received by the server becomes 123, and there is one more key=456
. This encoding method is called URL percent encoding, and its standard includes In RFC3986.
multipart/form-data
When set multipart/form-data
to , the browser does not encode characters, which is usually suitable for uploading files .
For multipart/form-data
request data in the format, the data will be segmented by special tags, and then passed in the request body.
text/plain
text/plain
When using the third method , the browser puts the request parameter body
into a string and processes it. This method is used to transmit the original HTTP message and does not apply any formatting processing.
Ajax
Next, let's take a look at Ajax that changed history . Because the page is refreshed every time the form is submitted , the experience is not very good. Ajax
It is a technology that can update some web pages without reloading the entire web page. So Ajax
the appearance undoubtedly changed history. The user experience is greatly improved.
The native we are talking about here Ajax
mainly introduces the XmlHttpRequest
use of XmlHttpRequest
objects to send asynchronous requests to the server and obtain data from the server.
basic process
Let's first take a look at the steps required to send the simplest one Ajax
.
create request object
First, you need to create a request object, and you need to consider browser compatibility when creating it.
let xhr;
if (window.XMLHttpRequest) {
// IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码
xhr = new XMLHttpRequest();
} else {
// IE6, IE5 浏览器执行代码
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
listen request
Before sending a request, we'd better listen to the request first, and readystatechange
the event will be executed at each stage of the request.
Generally, we only need to pay attention to the state of 4.
// 设置状态监听函数
xhr.onreadystatechange = function () {
// 4成功
if (this.readyState !== 4) return;
// xhr对象,在这里获取响应结果
console.log(this);
};
When a XMLHttpRequest
request is abort()
canceled by the method, its corresponding readystatechange
event will not be fired.
initialization request
The XMLHttpRequest.open(method, url, async) method initializes a newly created request, or re-initializes a request.
- method: the type of request; GET or POST
- url: request address
- async: true (asynchronous) or false (synchronous), the default is true
xhr.open(
"get",
`http://localhost:3000/testGet?name=randy&age=27` // 接口在文章末尾,使用node + express搭建
);
Set the return value type
After creating the request, we also need to set the type of response data, if not set, the default value will be used text
.
Commonly used return value formats are as follows
- "" is the same as text
- text
- json
- blob
- document
- arraybuffer
Here we respond to yes json
, so we need to set to josn
.
xhr.responseType = "json";
send request
XMLHttpRequest.send()
method for sending HTTP requests. If it is an asynchronous request (the default is asynchronous request), this method will return immediately after the request is sent; if it is a synchronous request, this method will not return until the response arrives (that is, it will prevent subsequent code execution).
XMLHttpRequest.send()
The method accepts an optional parameter, which is the request body; if the request method is GET or HEAD, the request body should be set to null.
Here because we are get
requesting, we can just send a null.
xhr.send(null)
send()
The data formats supported by the method are as follows, which post
will be used when requesting.
XMLHttpRequest.send();
XMLHttpRequest.send(String); // 传递js对象需要转成json字符串
XMLHttpRequest.send(URLSearchParams data);
XMLHttpRequest.send(FormData data);
XMLHttpRequest.send(ArrayBuffer data);
XMLHttpRequest.send(ArrayBufferView data);
XMLHttpRequest.send(Blob data);
XMLHttpRequest.send(Document data);
XMLHttpRequest.send(DOMString? data);
These request data formats need to be well known, otherwise passing unsupported data formats will cause request errors!
Get the response result
The response is actually in our onreadystatechange
listening event, let's take a look at what the successful xhr
object looks like.
Here we focus on response、status、statusText、readyState
these values.
response
property returns the body of the response. The returned type is one of ArrayBuffer
, Blob
, Document
, or string. JavaScript Object
This depends on the requested responseType
attribute . If not specified, the result defaults to text
type.
status
is the http status code.
statusText
Is the http status information.
readyState
is the state of the current request object.
in-depth
We gave an example of the simplest get
request earlier, let's take a closer look below. Such as post request, asynchronous, cancel request, error handling, etc.
send post request
The parameters of post
the request need to be placed send()
in the method, and multiple data formats are supported. Below, the author uses the three most frequently used data formats to explain.
Let's create a form first, here we no longer use the form to submit data, but use the Ajax
. So this form is just for us to get the data entered by the user. (Of course you can also not use the form).
<h3>form1</h3>
<form id="form1">
<input type="text" name="name" placeholder="请输入名字" />
<input type="number" name="age" placeholder="请输入年龄" />
<input type="button" id="submitBtn1" onclick="request1()" value="提交" />
</form>
<h3>结果</h3>
<div id="result"></div>
We then request1
create an xhr
object in the request method, initialize the request and monitor the request.
function request1() {
// 创建xhr
let xhr;
if (window.XMLHttpRequest) {
// IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码
xhr = new XMLHttpRequest();
} else {
// IE6, IE5 浏览器执行代码
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
// 设置状态监听函数
xhr.onreadystatechange = function () {
// 4成功
if (this.readyState !== 4) return;
// xhr对象
console.log(this);
// 将响应结果放到div显示
const resultDiv = document.getElementById("result");
resultDiv.innerText = this.response;
};
// 初始化请求
xhr.open("post", `http://localhost:3000/testPost`);
}
The default data format of the request body is text/plain
that we do not commonly use this kind of data in development, and generally use the following three data formats, so how to modify the data format we request? Then we have to use setRequestHeader
the method, which is to set our request header.
The request data format is application/x-www-form-urlencoded
// 设置我们请求数据的格式
// 对于 发送数据方式2,这个设置请求数据可以免去,因为它会自动设置
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
// 获取表单数据
const formData = new FormData(document.getElementById("form1"));
const name = formData.get("name");
const age = formData.get("age");
// 发送数据1
xhr.send(`name=${
name}&age=${
age}`);
// 发送数据方式2 直接借助 URLSearchParams 免去手动拼接参数
// const urlSearchParams = new URLSearchParams(formData);
// xhr.send(urlSearchParams);
Let's take a look at post
the effect of the request, and the result is returned successfully.
The request data format is application/josn
// 设置请求数据类型
xhr.setRequestHeader("Content-type","application/json");
// 获取表单数据
const formData = new FormData(document.getElementById("form1"));
const name = formData.get("name");
const age = formData.get("age");
// 发送json数据 需要转成字符串
xhr.send(JSON.stringify({
name, age }));
Let's take a look at post
the effect of the request, and the result is returned successfully.
The request data format is multipart/form-data
We generally use this data format to upload files, and it is not directly used to submit simple form data.
// 可以不设置 因为new FormData会自动将请求头设置为这种格式
xhr.setRequestHeader("Content-type","multipart/form-data");
// 获取表单数据
const formData = new FormData(document.getElementById("form1"));
// 初始化请求 使用第二个接口 使用multer特殊处理
xhr.open("post", `http://localhost:3000/testPost2`);
// 发送json数据 需要转成字符串
xhr.send(formData);
Let's take a look at post
the effect of the request, and the result is returned successfully.
asynchronous
Ajax
The default is asynchronous. When open
the third parameter of our method is set to false
, our request will be set to synchronous. Many friends think that synchronization means that the response result is send
the return value of the method, but it is not. The synchronous and asynchronous here just means blocking and not blocking the running of subsequent codes. The response results need to be readystatechange
obtained in the listening event.
Let's look at two examples
First look at asynchronous
xhr.open(
"get",
`http://localhost:3000/testGet?name=${
name}&age=${
age}`,
true
);
const result = xhr.send(null);
console.log(result);
console.log("后续代码");
Let's take a look at the output. An asynchronous request will not block subsequent code execution after the request, and send
the method will not return a result.
Let's look at synchronization again
xhr.open(
"get",
`http://localhost:3000/testGet?name=${
name}&age=${
age}`,
false
);
// 阻塞后续代码运行
const result = xhr.send(null);
console.log(result);
console.log("后续代码");
Let's take a look at the output. The synchronous request will block the execution of the subsequent code. The subsequent code will not run until the request has a result, and the send
method will not return the result.
cancel request
If the request has already been issued, the XMLHttpRequest.abort() method will terminate the request. When a request is terminated, its readyState
is set to 0, and the request's status
is set to 0.
xhr.abort();
error handling
The event is fired when a request encounters an error error
. However, it should be noted that errors returned by the backend will not trigger onerror
events, such as those returned by the backend 500 400
. The event will only be triggered when the network is interrupted or cross-domain onerror
.
// 设置请求失败时的监听函数
// 当网络中断或者跨域时会触发onerror事件
xhr.onerror = function () {
console.error(this);
};
AjaxSummary
- The entire request process is quite cumbersome from creating, monitoring, initializing the request, and sending the request, and the efficiency of development and use is definitely not high.
- The request method is relatively limited, only get and post requests are supported
- Promise is not supported, and the request result needs to be obtained through the monitoring function, and it is easy to nest for requests with dependencies .
- The data format transmitted by the request is relatively limited, and does not support the current mainstream native js objects (need to be converted into json strings).
- You need to manually set the response return value type, otherwise text type data will be returned by default
- Support Cancellation Request
jQuery Ajax
jQuery Ajax
Ajax
It is not a new thing, but an encapsulation of the original , making it easier to use and faster to develop.
$.ajax()
Before using ajax
to send a request, you need to go through a series of steps such as creating, monitoring, initializing the request, and sending the request, which is very troublesome. In jQuery
, one method can get it done.
Let's look at an example.
First import the pagejQuery
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
Then create a form.
<h3>form1</h3>
<form id="form1">
<input type="text" name="name" placeholder="请输入名字" />
<input type="number" name="age" placeholder="请输入年龄" />
<input type="button" id="submitBtn1" onclick="request2()" value="提交" />
</form>
<h3>结果</h3>
<div id="result"></div>
When the submit button is clicked, we send a get
request to the backend server.
function request2() {
$.ajax({
url: "http://localhost:3000/testGet", // 规定发送请求的 URL。默认是当前页面。
data: $("#form1").serialize(), // 规定要发送到服务器的数据。
success(result) {
console.log(result);
$("#result").text(JSON.stringify(result));
},
});
}
Let's see the effect. The data is normally fetched and returned
Let's take post
the request as an example to explain $.ajax()
the method in detail.
function request2() {
const formData = new FormData(document.getElementById("form1"));
const name = formData.get("name");
const age = formData.get("age");
$.ajax({
type: "POST", // 规定请求的类型(GET 或 POST) 默认GET
url: "http://localhost:3000/testPost2", // 规定发送请求的 URL。默认是当前页面。
// data: formData, // 上传文件需要用到,传送formData会自动设置contentType: "multipart/form-data",我们需要设置contentType: false、processData: false
// data: urlSearchParams, // 直接传递 URLSearchParams 对象 我们需要设置processData: false
data: `name=${
name}&age=${
age}`, // 规定要发送到服务器的数据。支持这种search字符串类型。可以使用$("#form1").serialize()直接序列化出来
// data: $("#form1").serialize(), // 把表单序列化成search字符串
// data: $.param({ name, age }), // 把对象序列化成search字符串
// data: { name, age }, // 支持对象类型
// data: JSON.stringify({ name, age }), // 支持对象字符串类型。使用这种方式需要设置 contentType: "application/json"
// contentType: "application/x-www-form-urlencoded", // 发送数据到服务器时所使用的内容类型。默认是:"application/x-www-form-urlencoded"。
// contentType: "application/json", // 发送数据到服务器时所使用的内容类型。默认是:"application/x-www-form-urlencoded"。
// contentType: false, // 不设置,当data是FormData是需要设置。
dataType: "", // 预期的服务器响应的数据类型。如果不指定,jQuery 将自动根据 HTTP 包 MIME 信息来智能判断。可以设置json、text、xml、html等
// processData: false, // 布尔值,规定通过请求发送的数据是否转换为查询字符串。默认是 true。
beforeSend(xhr) {
// 发送请求前运行的函数
console.log(xhr);
},
success(result) {
// 请求成功运行的函数
console.log(result);
$("#result").text(JSON.stringify(result));
},
error(xhr, status, error) {
// 如果请求失败要运行的函数
// 后端返回错误码也会进入该方法 比如 400/401/500
console.log(error);
},
complete(xhr, status) {
// 请求完成时运行的函数,不管成功或者失败
console.log(status);
},
});
}
Here we focus on data
, contentType
, processData
.
data
Only supports URLSearchParams
, FormData
, name=${name}&age=${age}
this search string, object, object string five forms. And need and contentType
corresponding.
At that time, only the form of object string can becontentType: "application/json"
passed .data
contentType: "application/x-www-form-urlencoded"
At that time, data
it can be a search string or an object, because the object will be automatically converted into a search character.
We can manually spell out the search string, and of course there is a more convenient method, which is $.serialize()和$.param()
the method of use.
data: $("#form1").serialize() // 表单序列化
data: $.param({
name, age }) // 对象序列化
When the parameter we pass data
is URLSearchParams
the format, it needs to be processData
set to false
turn off automatic conversion. Otherwise, an error will be reported.
When the parameter we pass data
is FormData
a format (usually when uploading a file), it needs to be processData
set to false
turn off automatic conversion. and also needs to be contentType
set to false
. Otherwise, an error will be reported.
Of course, if you think the above $.ajax()
method is too troublesome, we can also use the convenient methods corresponding to the request $.get()
, $.post()
, $.getJSON()
.
$.get()
$.get(URL,data,function(data,status,xhr),dataType)
method loads data from the server using an HTTP GET request. It has four parameters.
-
URL is required. Specifies the URL you need to request.
-
data is optional. Specifies the data sent to the server with the request. Only query string and object types are supported .
-
function is optional. Specifies a function to run when the request succeeds.
-
dataType is optional. Specifies the expected data type of the server response. By default, jQuery will intelligently judge
Here we simply try
$.get(
"http://localhost:3000/testGet",
$("#form1").serialize(),
function success(data, status, xhr) {
console.log(data);
$("#result").text(JSON.stringify(data));
},
"json"
);
can get the result correctly
$.post()
$.post(URL,data,function(data,status,xhr),dataType)
method loads data from the server using an HTTP POST request. It has four parameters.
-
URL is required. Specifies the URL you need to request.
-
data is optional. Specifies the data sent to the server with the request. Only query string and object types are supported .
-
function is optional. Specifies a function to run when the request succeeds.
-
dataType is optional. Specifies the expected data type of the server response. By default, jQuery will intelligently judge
Here we simply try
$.post(
"http://localhost:3000/testPost",
$("#form1").serialize(),
function success(data, status, xhr) {
console.log(data);
$("#result").text(JSON.stringify(data));
},
"json"
);
can get the result correctly
$.getJSON()
$.getJSON(url,data,function(data,status,xhr))
The method fetches JSON data using an AJAX HTTP GET request. It has three parameters.
-
URL is required. Specifies the URL you need to request.
-
data is optional. Specifies the data sent to the server with the request. Only query string and object types are supported .
-
function is optional. Specifies a function to run when the request succeeds.
Here we simply try
$.getJSON(
"http://localhost:3000/testGet",
$("#form1").serialize(),
function success(data, status, xhr) {
console.log(data);
$("#result").text(JSON.stringify(data));
}
);
can get the result correctly
It can be found that although the convenience method is more convenient to use, there are still many restrictions, especially the data transfer format, which only supports two types of query strings and objects . And there is no callback function for request errors, only successful callback functions.
jQuery AjaxSummary
- Compared with native Ajax, it encapsulates a series of methods, which is much more convenient to use.
- Compared with native Ajax, the request data format has been improved and native js objects are supported. It will automatically convert the native object into a search string and pass it on.
- Promise is not supported, the request result needs to be obtained through a callback function, and nesting is easy to occur for requests with dependencies.
- It is not mandatory to manually set the response return value type,
jQuery Ajax
it will be automatically set according to the return result. - Does not seem to support cancel requests
fetch
fetch(url, config)
method is used to initiate a request to obtain a resource. It returns a promise
, which promise
will be resolve
passed back to Response
the object after the request is responded to.
fetch()
It is not a native Ajax
encapsulation, but a request library natively supported by browsers.
Let's look at a simple example
fetch(`http://localhost:3000/testGet?name=randy&age=27`, {
})
.then((response) => {
console.log(response);
return response.json();
})
.then((res) => {
console.log(res);
});
output response
andres
It can be found that fetch()
after the request is completed, the result is not returned directly, but a Response object . It corresponds to the server's HTTP response. We will focus on this object later. response
is an Stream
object , we need to call some of its methods to get the data we want. For example, we called it above response.json()
. The function of this method is to convert the data into json
formatted data.
response object
ok
Response.ok
The attribute returns a Boolean value indicating whether the request is successful, true
corresponding to the status codes 200 to 299 of the HTTP request, and false
corresponding to other status codes.
status
Response.status
The property returns a number representing the status code of the HTTP response (eg 200 for a successful request).
statusText
Response.statusText
The property returns a string indicating the status information of the HTTP response (for example, the server returned "OK" after the request was successful).
url
Response.url
property returns the requested URL. If there is a jump in the URL, this property returns the final URL.
type
Response.type
Property returns the requested type. Possible values are as follows:
basic
: Ordinary requests, that is, same-origin requests.cors
: Cross-origin request.error
: Network errors, mainly for Service Workers.opaque
: If thefetch()
requestedtype
attribute is set tono-cors
, this value will be returned.opaqueredirect
: If thefetch()
requestedredirect
attribute is set tomanual
, this value will be returned.
redirected
Response.redirected
The property returns a boolean indicating whether the request has been redirected.
headers
Response
The object also has a Response.headers
property that points to a Headers object , corresponding to all the headers of the HTTP response.
Headers
The object provides the following methods for manipulating headers.
Headers.get()
: According to the specified key name, return the key value.Headers.has()
: Returns a boolean indicating whether a header is included.Headers.set()
: Set the specified key name as a new key value, if the key name does not exist, it will be added.Headers.append()
: Add headers.Headers.delete()
: Remove header.Headers.keys()
: Returns a traverser that can traverse all key names in turn.Headers.values()
: Returns a traverser that can traverse all key values in turn.Headers.entries()
: Returns a traverser that can traverse all key-value pairs ([key, value]
) in sequence.Headers.forEach()
: The headers are traversed in turn, and the parameter function will be executed once for each header.
For example, to get the responseContent-Type
response.headers.get('Content-Type'); // application/json; charset=utf-8
method of reading content
As we said earlier, the response content is response.body
above, but body
it is an ReadableStream
object, and we need further conversion to get the value we want.
What are the methods of conversion? We can call different read methods according to different types of data returned by the server.
response.text()
: get the text string.response.json()
: get JSON object.response.blob()
: Get a binary Blob object.response.formData()
: Get FormData form object.response.arrayBuffer()
: Get a binary ArrayBuffer object.
config parameter
fetch(url, config)
There are two parameters, url
which are the request address, so I won’t say more about this, let’s focus on it config
.
Here I will introduce several important config
parameters.
method
method: HTTP request method, GET
, POST
, DELETE
, PUT
are all set in this property.
headers
headers: An object used to customize HTTP headers. Such as commonly used content-type
.
body
body: The data body of the POST request. Get and Head requests cannot set this parameter .
Let's take a look at which request data types fetch supports? Let's look at an example of the author's test.
fetch(`http://localhost:3000/testPost`, {
method: "POST",
// body: "纯文本",
// body: formData, // 会自动设置 content-type 为 multipart/form-data
// body: urlSearchParams, // 会自动设置 application/x-www-form-urlencoded
// body: `name=${name}&age=${age}`, // 需要手动设置 "content-type": "application/x-www-form-urlencoded"
body: JSON.stringify({
name, age }), // 需要手动设置 "content-type": "application/json"
// 还支持 Blob 或 arrayBuffer,使用的比较少 这个笔者就不举例了
headers: {
// "content-type": "application/x-www-form-urlencoded",
"content-type": "application/json",
},
})
.then((response) => {
console.log(response);
// 转成字符串文本
return response.text();
})
.then((res) => {
const resultDiv = document.getElementById("result");
resultDiv.innerText = res;
});
fetch
text、FormData、URLSearchParams、search字符串、json字符串、Blob、arrayBuffer
The request data type in the format is supported and body
by default will 'text/plain;charset=UTF-8
send the request data in the format.
When the data format FormData
is , it will be automatically set content-type
as the request header multipart/form-data
of .
When the data format URLSearchParams
is , it will be automatically set content-type
as the request header multipart/x-www-form-urlencoded
of .
The transfer json
format data needs to be converted into json
a string, and the request header also needs to be "content-type": "application/json"
set .
mode
mode: Specifies the mode of the request. There are three possible values: cors, same-origin, no-cors
cors
: The default value, allowing cross-origin requests.same-origin
: Only same-origin requests are allowed.no-cors
: The request method is limited to GET, POST and HEAD, and only a few simple headers can be used, and cross-domain complex headers cannot be added, which is equivalent to the simple request that can be sent by submitting a form.
cache
cache
Attributes specify how to handle caching. Possible values are as follows:
default
: The default value, first look for matching requests in the cache.no-store
: Request the remote server directly without updating the cache.reload
: Directly request the remote server and update the cache.no-cache
: Compare the server resource with the local cache, use the server resource only if there is a new version, otherwise use the cache.force-cache
: Cache priority, only when there is no cache, the remote server is requested.only-if-cached
: Only check the cache, if it does not exist in the cache, a 504 error will be returned.
credentials
credentials
Property specifies whether to send cookies. Possible values are as follows:
same-origin
: The default value, cookies are sent for same-origin requests, and not sent for cross-origin requests.include
: Cookies are always sent regardless of same-origin requests or cross-domain requests.omit
: Never send.
How to judge whether the request is successful
fetch()
After sending the request, there is a very important point to note: only when there is a network error or when the connection cannot be made, an error fetch()
will be reported. In other cases, no error will be reported, but the request is considered successful. That is to say, even if the status code returned by the server is 4xx or 5xx, fetch()
no error will be reported (that is, the Promise will not change to rejected
status ).
So how to judge whether the request is successful
The first method is to Response.status
obtain the real status code of the HTTP response through attributes to determine whether the request is successful. That is to judge whether the status is between 200-300.
async function fetchTest() {
let response = await fetch(`http://localhost:3000/testGet?name=randy&age=27`);
if (response.status >= 200 && response.status < 300) {
// 请求成功
return await response.json();
} else {
// 请求失败
throw new Error(response.statusText);
}
}
Another way is to judge response.ok
whether it is true
. Because the value when status
in 200-300
between is .ok
true
if (response.ok) {
// 请求成功
} else {
// 请求失败
}
cancel request
fetch()
After the request is sent, if you want to cancel it halfway, it is also supported, and you need to use AbortController
the object.
Let's demonstrate
let controller = new AbortController();
let signal = controller.signal;
fetch(`http://localhost:3000/testGet?name=${
name}`, {
signal: controller.signal, // 需要传递signal参数
});
// 监听取消
// 也可以通过`controller.signal.aborted`属性判断取消信号是否已经发出。
signal.addEventListener("abort", () => console.log("signal abort!"));
// 取消
controller.abort();
It should be noted here that there is a one-to-one correspondence controller、signal
with fetch
the request parameters signal
. Whichever you call controller.abort()
will cancel the corresponding request. Of course, you can also use the same one controller
for multiple requests, so you can cancel multiple requests at once.
fetchSummary
- Support
promise
, more convenient, fast and efficient to use. - The obtained response needs to be further transformed to get the result we want.
- The error of the http status code needs to be judged by ourselves , because the error codes returned by the backend such as 400 and 500 will be resolved on the fetch side and treated as successful.
- The data format passed by the request is limited and does not support native js objects.
- The request method has also been expanded, not only supports get, post, but also supports put, delete and other request methods
- Get and head requests do not support passing request body parameters, and parameters can only be concatenated after the request path.
- Support Cancellation Request
Let's take a look at the most usedaxios
axios
axios
It's not a new thing, but a promise-based HTTP library that encapsulates native Ajax, which can be used in browsers and node.js.
So we need to introduce it before using it
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
Let's look at a simple example
<h3>axios form</h3>
<form id="form1">
<input type="text" name="name" placeholder="请输入名字" />
<input type="number" name="age" placeholder="请输入年龄" />
<input type="button" id="submitBtn1" onclick="request4()" value="提交" />
</form>
<h3>结果</h3>
<div id="result"></div>
We use axios(config)
to send a request.
function request4() {
const formData = new FormData(document.getElementById("form1"));
const name = formData.get("name");
const age = formData.get("age");
const urlSearchParams = new URLSearchParams(formData);
axios({
url: "http://localhost:3000/testGet",
params: urlSearchParams,
}).then((res) => {
// 响应数据在data中
console.log(res.data);
const resultDiv = document.getElementById("result");
resultDiv.innerText = JSON.stringify(res.data);
});
}
Let's see the effect
For axios
the focus on config
and response results response
, let's analyze them one by one.
config
Here I introduce several important config
parameters.
url
url
is the server URL for the request
method
HTTP request methods, GET
, POST
, DELETE
, PUT
are all set in this property.
baseURL
baseURL
will be automatically url
prepended unless url
is an absolute URL. Our configuration baseURL
can be simplified by setting .url
headers
Set request headers, such as common ones content-type
. We won't say much about this.
params
params
are the URL parameters that will be sent with the request. Must be a plain object or URLSearchParams object.
params
The parameter axios set in it will be automatically converted into a search string and spliced to the back of the request address.
data
data
is the data sent as the body of the request. Applies only to the request methods 'PUT', 'POST', and 'PATCH'.
transformRequest
When not set , must be one of the following types:
- string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
- Browser specific: FormData, File, Blob
- Exclusive to Node: Streams
When the data format FormData
is axios will automatically set to the request header ofcontent-type
.multipart/form-data
When the data format URLSearchParams
is axios will automatically set to the request header ofcontent-type
.application/x-www-form-urlencoded
When the data format plain object
is axios will automatically set to the request header ofcontent-type
.application/json
When you want to application/x-www-form-urlencoded
transfer data in format, there are usually three methods.
- You can pass
URLSearchParams
parameters. axios will automatically setcontent-type
asapplication/x-www-form-urlencoded
the request header of . - Pass
plain object
, but you need to manually setcontent-type
toapplication/x-www-form-urlencoded
the request header. qs
The search string is generated by the library for passing. Because when the data formatstring
is axios will automatically set tocontent-type
the request header.application/x-www-form-urlencoded
When you want to send a plain string, you need to manually set the request header content-type
to text/plain
.
responseType
responseType
Indicates the data type of the server response, which can be 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream'. After setting, axios
our response results will be converted automatically.
timeout
timeout
Specify the number of milliseconds for request timeout (0 means no timeout). The request will be aborted if it takes more timeout
than
withCredentials
withCredentials
Indicates whether it needs to be carried in cross-domain requests cookie
. The default is false
.
maxContentLength
maxContentLength
Defines the maximum size allowed for response content
After the configuration is understood, let's look at the responseresponse
response
data
data
The response provided by the server. Our response data is obtained in this property.
status
status
The HTTP status from the server response. For example, success will return 200.
statusText
statusText
HTTP status information from the server response. For example, success will return "OK"
.
headers
headers
server response header
config
Requested configuration information.
request
The request object, because axios
it is the right XMLHttpRequest
package, is an XMLHttpRequest
object.
create instance
We generally don't use it directly axios
, but create axios
an instance. axios
Supports creating a new axios
instance .
const instance = axios.create({
baseURL: '/api',
timeout: 1000,
headers: {
'content-type': 'application/json'}
});
// ...
Creating an instance has two benefits
First, we can configure the same configuration when creating an instance, so that there is no need to repeat the configuration in each request later.
Second, we can have multiple request instances in one system, and each instance can have its own unique configuration.
instance method
Each axios
instance can have its own request
request method, and there are also convenience methods.
The ones here config
will be merged with the ones used to create the instance above config
, and the same configuration will be overwritten.
instance.request(config)
This method is similar axios(config)
.
instance.get(url, config)
Send a get request directly
instance.delete(url, config)
Send a delete request directly
instance.head(url, config)
Send a head request directly
instance.options(url, config)
Send an options request directly
instance.post(url, data, config)
Send a post request directly, the second parameter is the request data.
instance.put(url, data, config)
Send a put request directly, and the second parameter is the request data.
instance.patch(url, data, config)
Send a patch request directly, the second parameter is the request data.
concurrent method
axios
Concurrent requests are also supported.
For example, send two requests at once.
axios
.all([
axios.get("http://localhost:3000/testGet", {
params: {
name: "jack" },
}),
axios.get("http://localhost:3000/testGet", {
params: {
name: "tom" },
}),
])
.then(
axios.spread((res1, res2) => {
console.log(res1);
console.log(res2);
})
)
.catch((err) => {
console.log(err);
});
By axios.all([请求1, 请求2...])
sending requests in batches, by axios.spread((请求1结果,请求2结果...) => {})
getting request results. Note that when one of the requests fails and the entire request fails , catch
the wrong one will be returned promise
.
error handling
axios
It will automatically analyze the response http status
code , if status
it is between 200 and 300, reslove
it will be successful, and the others will be rejected reject
.
Of course, if you want to customize the success status
range, you can configure the request parameter validateStatus
method
validateStatus: function (status) {
return status >= 200 && status < 300; // 默认是200-300
},
For error handling, there are generally two ways
// 通过 promise 的 catch
axios("http://localhost:3000/testGet", {
params: urlSearchParams,
})
.then((res) => {
console.log(res);
})
.catch((err) => {
console.log(err);
});
// 通过 try catch
try {
const res = await axios("http://localhost:3000/testGet", {
params: urlSearchParams,
});
console.log(res);
} catch (err) {
console.log(err);
}
cancel request
axios()
After the request is sent, if you want to cancel it halfway, it is also supported, and you need to use CancelToken
the object. Generally speaking, fetch
the configuration of and is very similar.
Let's demonstrate
const CancelToken = axios.CancelToken;
const source = CancelToken.source();
axios("http://localhost:3000/testGet", {
cancelToken: source.token, // 需要传递cancelToken
});
// 取消请求(message 参数是可选的)
source.cancel("Operation canceled by the user.");
It should be noted here that there is a one-to-one correspondence CancelToken
with axios
the request parameters cancelToken
. Whichever you call source.cancel()
will cancel the corresponding request. Of course, you can also use the same one cancelToken
for multiple requests, so you can cancel multiple requests at once.
axios
Also supports the second way to cancel the request
const CancelToken = axios.CancelToken;
let cancel;
axios("http://localhost:3000/testGet", {
cancelToken: new CancelToken(function executor(c) {
// executor 函数接收一个 cancel 函数作为参数
cancel = c;
}),
});
// 取消请求(message 参数是可选的)
cancel("Operation canceled by the user.");
axios
It fetch
seems that there is no canceling listener function.
axiosSummary
- Support
promise
, more convenient, fast and efficient to use. - Through configuration
responseType
, our response can be automatically converted into the corresponding format, basically no manual processing is required. - The error of the http status code does not need to be judged by ourselves . By default, only the status between 200-300 will be considered successful.
- The request body data parameter supports many data formats, and automatically sets the requested
content-type
value according to the format of the data we pass, which is very smart. - The request method has also been expanded, not only supports get, post, but also supports put, delete and other request methods. And provide a corresponding convenient method.
- Path parameters are not mandatory to be manually spliced after the path, but can be configured through params, and axios will automatically handle them.
- Provides request interception and response interception, which can process requests and responses in a unified manner, and the development efficiency will be higher.
- Cancellation requests are supported.
If you are interested in the application in , you can take a look at axios
the TS package Axios written by the author before.TypeScrit
Backend interface code
The interface is very simple, use node + express
to build
const express = require("express");
const app = express();
var cors = require("cors");
// 允许跨域
app.use(cors());
// 解析表单中 application/x-www-form-urlencoded 格式的数据
app.use(express.urlencoded({
extended: false }));
// 解析表单中application/json格式的数据
app.use(express.json());
// 解析表单中multipart/form-data格式的数据
const multer = require("multer");
const upload = multer();
app.get("/testGet", function (req, res, next) {
res.json(req.query);
});
app.post("/testPost", function (req, res, next) {
// 将请求体数据直接返回
res.send(req.body);
});
// 特殊处理multipart/form-data格式的数据
app.post("/testPost2", upload.none(), function (req, res, next) {
// 将请求体数据直接返回
res.send(req.body);
});
app.listen(3000, () => {
console.log("serve running on 3000");
});
postscript
Thank you friends for watching patiently. This article is the author's personal study notes. If there is any fallacy, please let me know. Thank you very much! If this article is helpful to you, please follow and like~, your support is the motivation for the author to keep updating!