ajax下载文件实现接受json数据和文件流两种形式
需求:前端下载文件,调用后端下载接口,如果后端报错需要给出错误信息如果没有报错可以正常下载。
解决方案:
方案一:首先想到的是分成两个接口首先询问是否可以下载,如果可以下载再去下载
方案二:通过原生ajax请求的状态码区分
function xhrGet (type ,url, fn){ // XMLHttpRequest对象用于在后台与服务器交换数据 var xhr = new XMLHttpRequest(); xhr.open(type, url, true); xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); xhr.setRequestHeader('Accept', 'application/json, text/plain, */*'); xhr.onreadystatechange = function() { // readyState == 4说明请求已完成 if(xhr.readyState == this.HEADERS_RECEIVED){ if(xhr.getResponseHeader('Content-Type')=='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'){ xhr.abort(); window.location.href=url; return; } } if (xhr.readyState == 4 && xhr.status == 200) { // 从服务器获得数据 try{ let res = JSON.parse(xhr.responseText); if(res.rc=='9'){ window.location.href=location.protocol+"//"+location.host+'/api/account/home?url='+encodeURIComponent(location.protocol+"//"+location.host+'/#/home'); return; } if(res.rc=='3'){ window.location.href="#/403"; return; } fn.call(this, res); }catch (error){ } } }; xhr.send(); }
我们onreadystatechange方法的回调函数是readyState,readyState标识不同的状态,当readyState==this.HEADERS_RECEIVED时,即服务器的相应头部已返回,那么我们获取头部的content-type,如果是application/json就是错误信息,执行正常的操。如果是下载文件对应的content-type,比如excel文件为'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',我们放弃该次,直接去访问该文件的下载地址即可正常下载。
附上readystate各阶段状态信息。