Fetch API 提供了一個 JavaScript 接口,用於訪問和操縱 HTTP 管道的部分,例如請求和響應。它還提供了一個全局 fetch()方法,該方法提供了一種簡單,合理的方式來跨網絡異步獲取資源。jquery
網絡異步獲取資源以前是用XMLHttpRequest
(例如常見的 jquery.ajax(),axios 都是這種)獲取的,Fetch 提供了一個更好的替代方法。現代瀏覽器基本都內置了,不用額外引入,IE 也能夠使用 polyfill 等一堆插件解決,其餘瀏覽器開箱即用。ios
不瞭解 Fetch 使用方法的這裏提供一下 MDN 的教程
// fetch-config.ts import Qs from 'qs' export enum ContentType { json = 'application/json;charset=UTF-8', form = 'application/x-www-form-urlencoded; charset=UTF-8' } export enum HttpMethod { get = 'GET', post = 'POST', put = 'PUT', patch = 'PATCH', delete = 'DELETE' } export interface IReqConfig { body?: any method?: string headers?: IHeader token?: string 'Content-Type'?: string } export interface IHeader { 'Content-Type': string 'X-Requested-With': string token: string [propName: string]: any } export const baseUrl = '/' const $req = async (url: string, config: IReqConfig) => { let promise: Response let contentType: string if (config['Content-Type'] !== undefined) { contentType = config['Content-Type'] } else if (config.method === HttpMethod.post) { contentType = ContentType.form } else { contentType = ContentType.json } const reqUrl = (baseUrl + url).replace('//', '/') const headers: Headers = new Headers({ // 若是實例配置沒傳token過來的話,直接使用保存在sessionStorage的token // 這裏假設後端直接讀頭文件的token字段,我直接用token當字段了,Authorization也同理 token: config.token === undefined ? sessionStorage.token : config.token, 'Content-Type': contentType } as IHeader) if (!config.method || config.method === HttpMethod.get) { promise = await fetch(reqUrl, { headers }) } else if (config.method === HttpMethod.post) { promise = await fetch(reqUrl, { body: Qs.stringify(config.body), headers, method: HttpMethod.post }) } else { promise = await fetch(reqUrl, { body: JSON.stringify(config.body), headers, method: config.method }) } return handleRes(promise) } const handleRes = async (res: Response) => { const parsedRes = await parseRes(res) // 若是res.ok,則請求成功 if (res.ok) { return parsedRes } // 請求失敗,返回解析以後的失敗的數據 const error = parsedRes throw error } const parseRes = async (res: Response) => { const contentType = res.headers.get('Content-Type') // 斷定返回的內容類型,作不一樣的處理 if (contentType) { if (contentType.indexOf('json') > -1) { return await res.json() } if (contentType.indexOf('text') > -1) { return await res.text() } if (contentType.indexOf('form') > -1) { return await res.formData() } if (contentType.indexOf('video') > -1) { return await res.blob() } } return await res.text() } export default $req
使用的時候ajax
// test.ts import $req, { HttpMethod } from './fetch-config' async function getMethod() { const getUrl: string = 'XXXX' try { const res: any = await $req(getUrl) } catch(e) { // 處理異常 } } async function postMethod() { const postUrl: string = 'XXXX' const reqBody: any = {/* request body */} try { const res: any = await $req(postUrl, { body: reqBody, method: HttpMethod.post }) } catch(e) { // 處理異常 } } async function patchMethod() { const patchUrl: string = 'XXXX' const reqBody: any = {/* request body */} try { const res: any = await $req(patchUrl, { body: reqBody, method: HttpMethod.patch }) } catch(e) { // 處理異常 } }
以上就是 fetch API 的簡單封裝,若是用的 JavaScript 的話,把類型和枚舉去掉就好,沒什麼差異json