起首声明一下,本文不是要解说fetch的详细用法,不清楚的能够参考 MDN fetch教程。
fetch默许不照顾cookie
设置其 credentials 项,其有3个值:
- omit: 默许值,疏忽cookie的发送
- same-origin: 示意cookie只能同域发送,不能跨域发送
- include: cookie既能够同域发送,也能够跨域发送
credentials所表达的寄义,实在与XHR2中的withCredentials属性相似,示意要求是不是照顾cookie
如许,若要fetch要求照顾cookie信息,只需设置一下credentials选项即可,比方fetch(url, {credentials: ‘include’});
fetch要求对某些毛病http状况不会reject
这主如果由fetch返回promise致使的,由于fetch返回的promise在某些毛病的http状况下如400、500等不会reject,相反它会被resolve;只要收集毛病会致使要求不能完成时,fetch 才会被 reject;所以平常会对fetch要求做一层封装,比方下面代码所示:
function checkStatus(response) {
if (response.status >= 200 && response.status < 300) {
return response;
}
const error = new Error(response.statusText);
error.response = response;
throw error;
}
function parseJSON(response) {
return response.json();
}
export default function request(url, options) {
let opt = options||{};
return fetch(url, {credentials: 'include', ...opt})
.then(checkStatus)
.then(parseJSON)
.then((data) => ( data ))
.catch((err) => ( err ));
}
fetch不支撑超时timeout处置惩罚
要领一:纯真setTimeout体式格局
var oldFetchfn = fetch; //阻拦原始的fetch要领
window.fetch = function(input, opts){//定义新的fetch要领,封装原有的fetch要领
return new Promise(function(resolve, reject){
var timeoutId = setTimeout(function(){
reject(new Error("fetch timeout"))
}, opts.timeout);
oldFetchfn(input, opts).then(
res=>{
clearTimeout(timeoutId);
resolve(res)
},
err=>{
clearTimeout(timeoutId);
reject(err)
}
)
})
}
固然在上面基础上能够模仿相似XHR的abort功用:
var oldFetchfn = fetch;
window.fetch = function(input, opts){
return new Promise(function(resolve, reject){
var abort_promise = function(){
reject(new Error("fetch abort"))
};
var p = oldFetchfn(input, opts).then(resolve, reject);
p.abort = abort_promise;
return p;
})
}
要领二:应用Promise.race要领
Promise.race要领接收一个promise实例数组参数,示意多个promise实例中任何一个最早转变状况,那末race要领返回的promise实例状况就随着转变,详细能够参考这里。
var oldFetchfn = fetch; //阻拦原始的fetch要领
window.fetch = function(input, opts){//定义新的fetch要领,封装原有的fetch要领
var fetchPromise = oldFetchfn(input, opts);
var timeoutPromise = new Promise(function(resolve, reject){
setTimeout(()=>{
reject(new Error("fetch timeout"))
}, opts.timeout)
});
retrun Promise.race([fetchPromise, timeoutPromise])
}
fetch不支撑JSONP
npm install fetch-jsonp --save-dev
然后在像下面一样运用:
fetchJsonp('/users.jsonp', {
timeout: 3000,
jsonpCallback: 'custom_callback'
})
.then(function(response) {
return response.json()
}).catch(function(ex) {
console.log('parsing failed', ex)
})
fetch不支撑progress事宜
XHR是原生支撑progress事宜的,比方下面代码如许:
var xhr = new XMLHttpRequest()
xhr.open('POST', '/uploads')
xhr.onload = function() {}
xhr.onerror = function() {}
function updateProgress (event) {
if (event.lengthComputable) {
var percent = Math.round((event.loaded / event.total) * 100)
console.log(percent)
}
xhr.upload.onprogress =updateProgress; //上传的progress事宜
xhr.onprogress = updateProgress; //下载的progress事宜
}
xhr.send();
然则fetch是不支撑有关progress事宜的;不过可喜的是,依据fetch的指点范例规范,其内部设想完成了Request和Response类;个中Response封装一些要领和属性,经由过程Response实例能够接见这些要领和属性,比方response.json()、response.body等等;
值得关注的处所是,response.body是一个可读字撙节对象,实在现了一个getRender()要领,其详细作用是:
getRender()要领用于读取相应的原始字撙节,该字撙节是能够轮回读取的,直至body内容传输完成;
因而,应用到这点能够模仿出fetch的progress
// fetch() returns a promise that resolves once headers have been received
fetch(url).then(response => {
// response.body is a readable stream.
// Calling getReader() gives us exclusive access to the stream's content
var reader = response.body.getReader();
var bytesReceived = 0;
// read() returns a promise that resolves when a value has been received
reader.read().then(function processResult(result) {
// Result objects contain two properties:
// done - true if the stream has already given you all its data.
// value - some data. Always undefined when done is true.
if (result.done) {
console.log("Fetch complete");
return;
}
// result.value for fetch streams is a Uint8Array
bytesReceived += result.value.length;
console.log('Received', bytesReceived, 'bytes of data so far');
// Read some more, and call this function again
return reader.read().then(processResult);
});
});
fetch跨域题目
fetch的mode设置项有3个值,以下:
- same-origin:该情势是不允许跨域的,它须要恪守同源战略,不然浏览器会返回一个error示知不能跨域;其对应的response type为basic。
- cors: 该情势支撑跨域要求,望文生义它是以CORS的情势跨域;固然该情势也能够同域要求不须要后端分外的CORS支撑;其对应的response type为cors。
- no-cors: 该情势用于跨域要求然则服务器不带CORS相应头,也就是服务端不支撑CORS;这也是fetch的特别跨域要求体式格局;其对应的response type为opaque。