The origin and definition of FETCH

The origin of the fetch

As we all know, traditional Ajax (XMLHttpRequest) is the earliest technology to send asynchronous requests, and its core is the use of XMLHttpRequest objects. But there are some headaches: XHR is a poorly designed API that doesn’t adhere to the principle of separation of concerns; Configuration and invocation are confusing, and the event-based asynchronous model is not as friendly to write as modern promises, generator/yield, async/await. Fetch was invented to solve the problem of XHR.

Definition and use of fetch

Description in MDN:
The Fetch API provides an interface to Fetch resources (including cross-domain requests). Anyone who has ever worked with XMLHttpRequest should be able to get started, but the new API offers a much more powerful and flexible set of features. But the dismal compatibility makes it difficult to use. I can wrap it myself and use Ajax instead for browsers that don’t support FETCH (see below).

The core of Fetch lies in the abstraction of HTTP interfaces, including Request, Response, Headers, Body, and global Fetch for initiating asynchronous requests. Where, the syntax definition of the global Fetch method is:

fetch(input[, init]); Input: Defines the resource to obtain. It can be a URL string for a resource, or it can be a Request object. Init: Optional, a configuration item object that contains all Settings for the request. Including: method, headers, body, mode, credentials such as return values: PromiseCopy the code
One thing to keep in mind: Fetch was designed based on Promise and is not a further encapsulation of Ajax, but a native JS API that does not use XMLHttpRequest objects.

Advantages and disadvantages of FETCH

Advantages:

1. Concise syntax, more semantic 2. Based on standard Promise implementation, support async/await 3. Isomorphism convenient, more low-level, provide rich API (Request, Response, body, headers) 5. XHR is a new implementation in the ES specificationCopy the code

Disadvantages:

1. Fetch reports errors only for network requests. 400,500 requests are regarded as successful, and the server does not reject 400,500 error codes. 2. The fetch does not carry cookies by default, so you need to add the configuration item: credentials:'include'. 3. Fetch does not support abort and timeout control, resulting in wasted traffic. 4. Fetch has no way of natively monitoring the progress of requests, whereas XHR doesCopy the code

Supplementary knowledge:

The Fetch mode configuration item has three values:

Same-origin: This mode is not allowed to cross domains and must comply with the same origin policy.
Cors: This pattern supports cross-domain requests, which, as the name implies, cross domains in the form of CORS;
No-cors: This mode is used for cross-domain requests but the server does not have a CORS response header, that is, the server does not support CORS.
Currently, the CORS pattern is a common implementation for cross-domain requests.

Fetch is perfectly encapsulated in vUE project

Very few words, directly attached code.

Env.js file, as follows:

/** * baseUrl: domain name address * routerMode: routing mode */let baseUrl = ' ';
let routerMode = 'history';
if (process.env.NODE_ENV == 'development') {  
    baseUrl = 'http://localhost:3000';
}else{  
    baseUrl = 'http://xxxx here is the online address XXX ';
}

export { baseUrl, routerMode }

Copy the code

The fetch. Js file is as follows:

import { baseUrl } from './env'
export default async(url = ' ', data = {}, type = 'GET', method = 'fetch') = > {type= type.toUpperCase(); url = baseUrl + url; // The parameters of the GET request are used in data, as in the POST requestif (type= ='GET') {
		let dataStr = ' '; 
		Object.keys(data).forEach(key => {
			dataStr += key + '=' + data[key] + '&';
		})
 
		if(dataStr ! = =' ') {
			dataStr = dataStr.substr(0, dataStr.lastIndexOf('&'));
			url = url + '? '+ dataStr; }} // For browsers that support the fetch method, the processing is as follows:if (window.fetch && method == 'fetch') {
		letRequestConfig = {// fetch does not carry cookies by default, so you need to add configuration items to allow cookie credentials:'include', 
			method: type,
			headers: {
				'Accept': 'application/json'.'Content-Type': 'application/json'
			},
			mode: "cors"// Cross-domain cache in the form of CORS:"force-cache"
		}
 
		if (type= ='POST') {
			Object.defineProperty(requestConfig, 'body', {
				value: JSON.stringify(data)
			})
		}
		
		try {
			const response = await fetch(url, requestConfig);
			const responseJson = await response.json();
			return responseJson
		} catch (error) {
			throw new Error(error)
		}
	} else{// For browsers that do not support FETCH, Ajax + Promise is automatically usedreturn new Promise((resolve, reject) => {
			let requestObj;
			if (window.XMLHttpRequest) {
				requestObj = new XMLHttpRequest();
			} else{ requestObj = new ActiveXObject; // Compatible with IE}let sendData = ' ';
			if (type= ='POST') {
				sendData = JSON.stringify(data);
			}
 
			requestObj.open(type, url, true);
			requestObj.setRequestHeader("Content-type"."application/x-www-form-urlencoded");
			requestObj.send(sendData);
 
			requestObj.onreadystatechange = () => {
				if (requestObj.readyState == 4) {
					if (requestObj.status == 200) {
						let obj = requestObj.response
						if(typeof obj ! = ='object') {
							obj = JSON.parse(obj);
						}
						resolve(obj)
					} else {
						reject(requestObj)
					}
				}
			}
		})
	}
}
Copy the code

 

The above code, effective test. Over, thanks !