Ajax方式實現文件下載失敗

背景:實現文件下載導出

問題描述

前端發送ajax【get/post】請求,後端生成excel文件,最後用response輸出文件流,沒有報錯也沒有文件下載提示。

遇到過這個問題的仍是很多,問題出在ajax自己,解決方法和緣由也都找到。html

緣由:文件的下載是以二進制形式進行的,ajax沒法解析後臺返回的文件流,因此沒法處理二進制流response輸出來下載文件前端

  ajax請求只是個「字符型」的請求,即請求的內容是以文本類型存放的。文件的下載是以二進制形式進行的,ajax無法解析後臺返回的文件流,因此沒法處理二進制流response輸出來下載文件。
   ajax的返回值類型是json,text,html,xml類型,或者能夠說ajax的接收類型只能是string字符串,不是流類型,因此沒法實現文件下載。但用ajax仍然能夠得到文件的內容,該文件將被保留在內存中,沒法將文件保存到磁盤。
 這是由於JavaScript沒法和磁盤進行交互,不然這會是一個嚴重的安全問題,js沒法調用到瀏覽器的下載處理機制和程序,會被瀏覽器阻塞。

解決方式

  • 隱藏表單,用提交表單的形式
  • 用window.open() 或 window.location.href()
  • 建立iframe,iframe的src能夠是文件地址url來直接下載文件

1)使用window.location.href=dataUrl;就能夠實現。ajax

window.location.href=basePath+'invoiceFormBillAttachAction/downloadAttaches.do?ID='+ID+'&REMARK='+REMARK;

2) 使用隱藏iframe實現無刷新下載文件json

      <a href="#" onclick="downloadFile()">download</a>
      <iframe id="ifile" style="display:none"></iframe>
      function downloadFile(){
        var dom=document.getElementById('ifile');
        dom.src="http:xxxx.com";
     }

3) 分裝form表單請求後端

download() {
          if (this.cloudDiskIds.length == 0) {
              alert ("請選擇要下載的文件!")
              return
          }
          if (this.cloudDiskIds.length > 1) {
              alert ("只能選擇一個文件!")
              return
          }
          // this.formData.fileName = this.cloudDiskList[0].fileName;
          // this.formData.filePath = this.cloudDiskList[0].filePath;
          // alert (this.cloudDiskIds[0])
          // 請求地址
          var url = "http://localhost:8080/wingCloud/customer/download";
          // 分裝form表單
          var form = $("<form></form>").attr("action", url).attr("method", "post");
          // 封裝參數
          form.append($("<input></input>").attr("type", "hidden").attr("name", "id").attr("value", this.cloudDiskIds[0]));
          // form.append($("<input></input>").attr("type", "hidden").attr("name", "filePath").attr("value", this.formData.filePath));
          // 提交
          form.appendTo('body').submit().remove();
      }
相關文章
相關標籤/搜索