What is Fetch?
Fetch is a JavaScript interface, an ideal alternative to XMLHttpRequest, for asynchronously fetching resources (HTTP requests) across a network.
A basic FETCH request is simple to set up. Look at the following code:
fetch('http://example.com/movies.json')
.then((response) => {
return response.json();
})
.then((myJson) => {
console.log(myJson);
});
Copy the code
Dai Yu tong “come late” : I this time, after all or come too late
Just as a review XMLHttpRequest gets data (Ajax)
Step: 1. Create XmlHttpRequest object 2. Call open method to set basic request information 3. Set the data to send and send the request. 4. Register the callback function to listen to. 5
If (window.xmlHttprequest){var oAjax=new XMLHttpRequest(); }else{// compatible ie var oAjax=new ActiveXObject(" microsoft.xmlhttp "); Oajax.open ('GET', URL, true); //2. / / 3. Send oAjax. The send (); Onreadystatechange =function (){if(oajax.readystate ==4){if(oajax.status ==200){//alert(' successful: '+oAjax.responseText); fnSucc(oAjax.responseText); }else{//alert(' failed '); if(fnFaild){ fnFaild(); }}}};Copy the code
The fetch encapsulation
Fetch parameters (feach (URL, optionObj))
A POST request
const response = await fetch(url, {
method: 'POST',
headers: {
"Content-type": "application/json; charset=UTF-8",
},
body: 'foo=bar&lorem=ipsum',
});
const json = await response.json();
Copy the code
The configuration object uses three properties
method
: Method of HTTP request,POST
,DELETE
,PUT
It’s all in this property setting.headers
: An object that is used to customize the headers of HTTP requests.body
: The body of the POST request.
Some headers cannot be set via the headers property, such as content-length, Cookie, Host, and so on. They are automatically generated by the browser and cannot be modified.
Adding JSON Data
const user = { name: 'John', surname: 'Smith' }; const response = await fetch('/article/fetch/post/user', { method: 'POST', headers: { 'Content-Type': 'application/json; charset=utf-8' }, body: JSON.stringify(user) });Copy the code
Encapsulate a fetch of its own (forms not supported)
interface IInit extendsRequestInit { body? : BodyInit |null| any; prefix? :'api' | 'api1';
}
export default function fetch(url: string, init? : IInit) {
if(! init) init = {};const prefix = init.prefix ? uPrefix[init.prefix] : uPrefix.api;
if(! init.credentials) init.credentials ='include'; // By default, cookies are sent for both same-origin and cross-domain requests.
if (init.body && typeof init.body === 'object') init.body = JSON.stringify(init.body); // Convert the JSON string
if(init.body && ! init.method) init.method ='POST'; // There is a body, the default request method is POST
if (init.method) init.method = init.method.toUpperCase(); // Convert the string to uppercase
if (['POST'.'PUT'.'DELETE'].includes(init.method || ' ')) { // Submit JSON data, default is 'text/plain; charset=UTF-8'
init.headers = Object.assign({}, init.headers || {
'Content-Type': 'application/json'}); } init = addCustomHeader(init)const realUrl = `${prefix}${url}`;
return window
.fetch(realUrl, init)
.then(res= > checkStatus(res)) // Check the response code
.then((res) = > res.json())
.then((res) = > filter(res)) // Filter based on service requirements
.catch(err= > console.log('Request failed! + url:${realUrl}`, err));
}
Copy the code
fetch()
Complete API for configuration objects
The full API for the second argument of fetch() is as follows.
const response = fetch(url, { method: "GET", headers: { "Content-Type": "text/plain; charset=UTF-8" }, body: undefined, referrer: "about:client", referrerPolicy: "no-referrer-when-downgrade", mode: "cors", credentials: "same-origin", cache: "default", redirect: "follow", integrity: "", keepalive: false, signal: undefined });Copy the code
cache
The cache property specifies how the cache is handled. Possible values are as follows:
default
: the default value, which is used to look for matching requests in the cache.no-store
: Requests the remote server directly and does not update the cache.reload
: Requests the remote server directly and updates the cache.no-cache
: Compares server resources to the local cache. Use server resources only if there is a new version, otherwise use cache.force-cache
: Cache takes precedence. Request the remote server only if no cache exists.only-if-cached
: check only the cache, if the cache does not exist, return error 504.
mode
The mode attribute specifies the mode of the request. Possible values are as follows:
cors
: The default value allows cross-domain requests.same-origin
: Only same-origin requests are allowed.no-cors
: Request methods are limited to GET, POST, and HEAD, and can only use a limited number of simple headers. You cannot add complex cross-domain headers, equivalent to the request that can be made by submitting a form.
credentials
The credentials attribute specifies whether to send cookies. Possible values are as follows:
same-origin
: The default value. Cookie is sent for same-origin requests but not for cross-domain requests.include
: Cookie is sent regardless of the same origin request or cross-domain request.omit
: All do not send.
To send cookies for cross-domain requests, set the credentials attribute to include.
fetch('http://another.com', { credentials: "include" }); Copy the code
signal
The signal property specifies an AbortSignal instance to cancel the fetch() request, as described in the next section.
keepalive
The Keepalive property is used when a page is uninstalled to tell the browser to stay connected in the background and continue sending data.
A typical scenario is when a user leaves a web page and the script submits some statistics about the user’s behavior to the server. At this point, without the Keepalive property, the data may not be sent because the browser has already uninstalled the page.
window.onunload = function() { fetch('/analytics', { method: 'POST', body: "statistics", keepalive: true }); }; Copy the code
redirect
The redirect attribute specifies how HTTP redirects are handled. Possible values are as follows:
follow
: Default value,fetch()
Follow the HTTP jump.error
: If a jump occurs,fetch()
Is an error.manual
:fetch()
Does not follow the HTTP jump, howeverresponse.url
Property will point to the new URL,response.redirected
The property will change totrue
, it is up to the developer to decide how to handle the jump afterwards.
integrity
The integrity property specifies a hash value to check whether the data returned by the HTTP response is equal to the preset hash value.
For example, when downloading a file, check that the sha-256 hash of the file matches to make sure it hasn’t been tampered with.
fetch('http://site.com/file', { integrity: 'sha256-abcdef' }); Copy the code
referrer
The referrer property is used to set the referer header for the fetch() request.
This property can be any string or it can be set to an empty string (that is, no referer header is sent).
fetch('/page', { referrer: '' }); Copy the code
referrerPolicy
The referrerPolicy attribute is used to set the rules for the Referer header. Possible values are as follows:
no-referrer-when-downgrade
: Default value, always sendReferer
Header, unless an HTTP resource is requested from an HTTPS page.no-referrer
: don’t sendReferer
The headers.origin
:Referer
The header contains only the domain name, not the full path.origin-when-cross-origin
: Same source requestReferer
The header contains the full path, and the cross-domain request contains only the domain name.same-origin
: The cross-domain request is not sentReferer
, the same source request is sent.strict-origin
:Referer
The header contains only the domain name and is not sent when an HTTPS page requests HTTP resourcesReferer
The headers.strict-origin-when-cross-origin
: Same-origin requestReferer
The header contains the full path, only the domain name for cross-domain requests, and is not sent when an HTTPS page requests HTTP resources.unsafe-url
: Always send no matter whatReferer
The headers.
cancelfetch()
request
If you want to cancel the fetch() request after it has been sent, you need to use the AbortController object.
let controller = new AbortController(); let signal = controller.signal; fetch(url, { signal: controller.signal }); signal.addEventListener('abort', () => console.log('abort! ')); controller.abort(); / / cancel the console. The log (signal. Aborted); // trueCopy the code
In the example above, the AbortController instance is created first and the fetch() request is sent. The signal property of the configuration object must specify that the AbortController instance is sent to receive controller.signal.
The controller.abort() method is used to signal cancellation. Will trigger the abort event at this moment, this event can listen, but can be by the controller. The signal. The aborted attribute to determine whether a cancellation signal has been issued.
Start building Axios
1. Clone the Demo project
git clone https://gitee.com/dengruifeng/wabpack-demo
Copy the code
Establish the fetch. Ts
import { notification } from 'antd';
const window = self.window;
export interface IRes { // The format agreed with the backend
code: number;
message: string;
data: any;
}
interface IInit extendsRequestInit { body? : BodyInit |null | any;
}
const checkStatus = (res: Response) = > {
if (res.status === 401) {
window.location.href = '/login';
}
if (res.status === 405 || res.status === 403) {
location.href = '/ 403';
}
if (res.status === 404) {
notification.error({ message: 'Interface does not exist' });
}
return res;
};
const filter = (res: IRes) = > {
// if (res.code ! == 0 && res.code ! = = 200) {
// notification.error({
// message: '错误',
/ / description: res. Message | | 'service error, please try again! ',
/ /});
// throw res;
// }
res.data = res;
return res.data; // Return the data
};
const addCustomHeader = (init? : IInit) = > { // Add a custom header
init = init || {};
init.headers = Object.assign(init? .headers || {}, {// 'X-SSO-USER': 'admin',
});
return init;
};
export default function fetch(url: string, init? : IInit) {
if(! init) init = {};// if (! init.credentials) init.credentials = 'include'; // The default is same-origin, include. Cookie is sent regardless of the same origin request or cross-domain request.
if (init.body && typeof init.body === 'object') init.body = JSON.stringify(init.body); // Convert the JSON string
if(init.body && ! init.method) init.method ='POST'; // There is a body, the default request method is POST
if (init.method) init.method = init.method.toUpperCase(); // Convert the string to uppercase
if (['POST'.'PUT'.'DELETE'].includes(init.method || ' ')) { // Submit JSON data, default is 'text/plain; charset=UTF-8'
init.headers = Object.assign({}, init.headers || {
'Content-Type': 'application/json'}); } init = addCustomHeader(init);console.log(init);
return window
.fetch(url, init)
.then(res= > checkStatus(res)) // Check the response code
.then((res) = > res.json())
.then((res) = > filter(res)) // Filter based on service requirements
.catch(err= > console.log('Request failed! + url:${url}`, err));
}
export function formFetch(url: string, init? : IInit) { // Form fetch, used to upload files, etc
if(! init) init = {}; init = addCustomHeader(init)return window
.fetch(url, init)
.then(res= > checkStatus(res))
.then((res) = > res.json())
.then((res) = > filter(res))
.catch(err= > console.log('Request failed! + url:${url}`, err));
}
Copy the code
Find a free API to test Baidu has many resources I find here api.uomg.com/doc-rand.im…
Create the API interface file
import fetch from '.. /utils/fetch';
export const getImgList = (sort: string) = > {
return fetch(`https://api.uomg.com/api/rand.img1?sort=${sort}&format=json`);
};
Copy the code
Use on the page
import { Input, Tag } from 'antd';
import { getImgList } from 'api/test';
import React from 'react';
import { Link } from 'react-router-dom';
import './index.less';
export const Page1 = () = > {
const [imgurl, setData] = React.useState(' ');
const [sort, setsort] = React.useState('beauty');
React.useEffect(() = > {
getData();
}, [sort]);
const getData = () = > {
getImgList(sort).then((res: { imgurl: string }) = > {
console.log(res);
setData(res.imgurl);
});
};
return (
<div className="test-css">
<h1 className="test-css-home">I am a Page1</h1>
<Link to={'/'} >
<Tag>Return to the home page</Tag>
</Link>
<h2>Search images</h2>
<Input.Search
style={{ width: 300 }}
placeholder="Enter keywords such as: beauty, wallpaper, etc."
onSearch={(value: string) = > setsort(value)}
enterButton
/>
<br />
<img src={imgurl} alt="img" />
</div>
);
};
Copy the code
View the complete process and see the project code for yourself
Uploading files (formFetch)
The uploaded files are included in the entire form and submitted together. The file is uploaded using the form
const handleChange = (e: UploadChangeParam) = > {
const file = e.fileList[0]? .originFileObj;// File stream object
const fileName = e.fileList[0].name; / / file name
const formData = new FormData();
formData.append('uploadFile', file as any);
formData.append('fileName', fileName);
upload(formData).then((res) = > {
console.log(res);
});
};
Copy the code
export const upload = (obj: FormData) = > {
return formFetch(`/v3/normal/ecm/package`, {
method: 'POST'.body: obj,
});
};
Copy the code
The browser will display it like this
Upload binary data directly
let blob = await new Promise(resolve =>
canvasElem.toBlob(resolve, 'image/png')
);
let response = await fetch('/article/fetch/post/image', {
method: 'POST',
body: blob
});
Copy the code
reference
# Fetch API tutorial – Untested cancel Fetch request repository: gitee.com/dengruifeng…