fetch的使用与封装

2,952 阅读1分钟

fetch的使用

fetch是es6新增的内置方法,用来实现http请求,ajax也是js原生的内容,jquery和axios(基于promise和ajax的封装),是基于一些方式对ajax的封装

let url=""
options={
	body:"",
	method:"post",
    credentials: 'include', 
    // include(同源非同源), same-origin(同源), *omit(不可以携带资源凭证)
    headers:{
    	'content-type': 'application/x-www-form-urlencoded'
    }
}
fetch(url,options).then(response=>{
	console.log(response.json())
}).catch(reason=>{
	
})

封装fetch

首先要把封装的方法放到一个闭包里,保护它不被外界影响,向外暴漏方法request,为request对象添加defautls属性,用来设置默认值,调用request方法,传入options配置项,通过initOptions方法把默认值与新的options合并,用得到的options去得到fetch方法中url和options,使用then接收相应回来的值,通过status判断是否相应成功进行进一步操作

(function(){
let isOk=/^(2|3)\d{2}$/
let isGet=/^(get|head|detele|options )$/i
//Object.assign是浅合并,如果传入的options中有headers要先把headers合并
function initOptions(options){
	let oldOptions=request.defaults
	if(options.header){
    //处理headers,把headers合并之后赋值给传入的headers
    	options.header=Object.assign(oldOptions.headers,options.header)
    }
    return Object.assign(oldOptions,options)
}

handleUrl(options){
	let {
    	baseUrl,
        url,
        method,
        body
    }=options
    url=baseURl+url
    if(isGet.test(method)&&body){
    	url=formateUrl(url,body)
    }
    return url
}
handleOptions(options){
	let config={
    	method:options.method,
        credentials:options.credentials,
        headers:options.headers,
        
    }
    if(!isGet.test(options.method)){
    	config.body:options.transform(options.body)
    }
    return config
}

function formateUrl(url,body){
	let str=``
	for(let k in body){
    	str+=`&${k}=${body[k]}`
    }
    str=str.substring(1)
    url=url.includes("?")?url+"&"+str:url+"?"+str
    return url
}

function request(options){
	options=initOptions(options)
    fetch(handleUrl(options),handleOptions(options)).then(response=>{
    	let status=response.status
        if(isOk.test(status)){
        	let result=response.json()
        	switch(options.responseType){
				case "text":
                	result=response.text()
                    break;
                case "blob":
                	result=response.blob()
                    break;
               	case "arrayBuffer":
                	result=response.arrayBuffer()
                    break;
            }
            return result
        }else{
        	switch(status){
				case "404":
                	
                    break;
                case "500":
                	
                    break;
               	case "401":
                	
                    break;
            }
            return Promise.reject("...")
        }
    }).catch(reason=>{
    	if(!window.navigator.onLine){
        	//...
        }
        return Promise.reject()
    })
}

//设置默认参数
request.defaults={
	baseUrl:"",
    url:"",
    body:{},
    method:"get",
    credentials: 'include',
    headers:{
   		'content-type': 'application/x-www-form-urlencoded'
    },
    transformRequest:data=>JSON.stringify(data),
    responseType:"json"
}

//把api导出
	if(window.window===window){
		window.request=request
	}
	if(typeof module==="object"&& typeof module.exports==="object"){
		module.exports=request
	}
})()