/** * Common request methods * support get and post types * file and other types of processing other methods *@param apiUrl
* @param method 'get' || 'post'
* @param body object
* @param contentType 'json' || ''
* @returns {Promise<Response | never>}* /
const fetchApi = ( apiUrl, method, body, contentType ) = > {
if( process.env.NODE_ENV === 'development' ) {
console.log('Request address ====================', apiUrl);
console.log('Request parameters ====================', body);
}
// requestPath is the public request address
let url = requestPath + apiUrl ;
If the parameters are the same, the browser directly uses the cached data. The page is the same as the original page, so a timestamp is added to the request
body.timeStamp = new Date().getTime();
const fetchOptions = {}
fetchOptions.method = method || 'get';
fetchOptions.credentials = 'include';
fetchOptions.mode = 'no-cors';
if (fetchOptions.method === 'get') {
url = getRequestBodyHandler(url, body)
}
if (fetchOptions.method === 'post') {
// application/json
if (contentType === 'json') {
fetchOptions.headers = {
'Accept': 'application/json'.'Content-Type': 'application/json'
}
// The configuration here is to fetch across domains
fetchOptions.mode = 'cors';
fetchOptions.cache = 'force-cache';
fetchOptions.body = fetchJsonBodyHandler(body)
} else { // form data
fetchOptions.body = postRequestBodyHandler(body)
}
}
return fetch(url, fetchOptions)
.then(checkServerStatus)
.then(parseJSON)
.then(checkServerDataStatus);
}
Copy the code
Description and handling of fetch requests across domains
There are two types of CORS:
-
A simple request
Some requests do not trigger CORS precheck requests. This article calls such a request a “simple request.” A request is considered a “simple request” if all of the following conditions are met:
- Use one of the following methods: GET HEAD POST
- The Fetch specification defines a set of header fields that are CORS safe. No header fields other than this set may be set artificially. Accept accept-language content-language content-type DPR Downlink save-data viewport-width Width
- Content-type values are one of the following: Application/X-www-form-urlencoded multipart/form-data text/plain
-
CORS with preFlight pre-request
With preflight CORS, the browser will issue an OPTIONS request, and the server will write in the response whether to allow access to the domain name. Access-control-allow-origin, access-contral-allow-methods, access-Contraol-allow-headers, access-contr are added to the header of response Ol-max-age these fields.
Make a CORS request with credentials
By default, cookies are not sent to the server for cross-domain requests. In the case that cookies need to be sent, xhr.withCredentials = true should be set if XHR is used. The credentials:’include’ need to be set in the request. However, if the server does not return access-Control-allow-crenditials :true, then the server can set the credentials:’include’ in the request. Cookies will not be sent to the server, so pay special attention to the simple GET request, there is no pre-request process, so in the actual request, If the server does not return access-Control-allow-crenditials :true then the browser will not hand the response to the requester.
About the fetch cross-domain illustrate source address: blog.csdn.net/danzhang101…
Actual problems encountered
The latter interface specifies that only POST requests are received, so a FETCH request with a pre-request returns 405. To handle this, add the following configuration to your code:
fetchOptions.mode = 'cors';
fetchOptions.cache = 'force-cache';
Copy the code
Other auxiliary methods
/** * Add json request parameters to the URL *@param url
* @param ob
* @returns {*}* /
const getRequestBodyHandler = function (url, ob) {
if (ob) {
let param = ' '
Object.keys(ob).forEach((key, value) = > {
param ? (param += '&') : (param += '? ')
param += (key + '=' + ob[key])
})
return url + param
}
return url
}
Copy the code
/** * Convert json request parameters to formData body * when a POST request is made@param ob
* @returns {*}* /
const postRequestBodyHandler = function (ob) {
if (ob) {
const body = new FormData()
Object.keys(ob).forEach((key) = > {
body.append(key, ob[key])
})
return body
}
return null
}
Copy the code
const fetchJsonBodyHandler = function (ob) {
return typeof ob === 'object' ? JSON.stringify(ob) : ob
}
Copy the code
/** * Interface data status verification *@param data
* @returns {*}* /
const checkServerDataStatus = (data) = > {
if( process.env.NODE_ENV === 'development') {console.log('Request return data ====================', data)
}
// Successful return
if ( data && (data.status === 200 || data.state === 0)) {
return data.data ;
}
// Error handling
const errorInfoMap = {
99999: {type: 'dataException'.msg: 'Data exception'
},
100000: {
type: 'unknown'.msg: 'Unknown exception'
},
500 : {
type: 'exception'.msg: 'Interface exception'
},
501 : {
type: 'exception'.msg: 'Interface exception'
},
502 : {
type: 'exception'.msg: 'Interface exception'
},
503 : {
type: 'exception'.msg: 'Interface exception'
},
401 : {
type: 'noPrmission'.msg: 'No access permission'
},
403: {
type: 'refuse'.msg: 'Interface access denied'
},
404: {
type: 'notFound'.msg: 'Interface link does not exist'}}// Error message
let errorInfo = {
type: 'unknown'.msg: 'Unknown exception'
}
// Error object
const error = new Error(a);// The data format is abnormal
if(! data || ! data.status ){Object.assign( error, errorInfo, errorInfoMap[99999]);throw error;
}
// Error caught according to code
let extraErrorInfo = errorInfoMap[ data.status ];
if( extraErrorInfo ){
Object.assign( error, errorInfo, extraErrorInfo );
throw error;
}
// Unknown error
throw error
}
Copy the code
/** * Server request status validation *@param data
* @returns {*}* /
const checkServerStatus = (response) = > {
// Request accepted successfully
if (response.status >= 200 && response.status < 300) {
return response
} else {
// Error handling
const errorInfoMap = {
100000: {
type: 'serverUnknown'.msg: 'Server: Unknown exception'
},
502 : {
type: 'serverMaintainace'.msg: 'Server: Server in maintenance'
},
404 : {
type: 'serverException'.msg: 'Server: access address does not exist'}}// Error message
let errorInfo = {
type: 'serverUnknown'.msg: 'Server: Unknown exception'
}
// Error object
const error = new Error(a);// Error caught according to code
let extraErrorInfo = errorInfoMap[ response.status ];
if( extraErrorInfo ){
Object.assign( error, errorInfo, extraErrorInfo );
throw error;
}
// Unknown error
throw error
}
}
Copy the code
/ / the json conversion
const parseJSON = (response) = > {
//response.text() gets the text type
// Response.json () will help you run json.parse (response.text()) once
return response.json()
}
Copy the code