【解決】AJAX 沒辦法收取檔案 回應(檔案下載)的問題

常見問題

為何Ajax無法檔案載

AJAX(Asynchronous Javascript And XML)翻譯成中文就是「非同步的Javascript和XML」。即使用Javascript語言與伺服器進行非同步交互,傳輸的數據為XML。

AJAX 其中一項最重要的作用是「非同步處理」,即可以透過 AJAX 發出 HttpRequest 向伺服器索取想要的資料,且畫面不需要為了取得部份的資料,而刷新整個頁面。

    a.同步交互:客戶端發出一個請求後,需要等待伺服器響應結束後,才能發出第二個請求;

    b.非同步交互:客戶端發出一個請求後,無需等待伺服器響應結束,就可以發出第二個請求。

然而伺服器對 Ajax 資料請求回應通常是以(xml、json、script、html )資料格式(dataType)其中之一,可以發現全部都是屬於「文字」型態的格式,也就是說ajax 本身就不是設計來下載檔案使用的(參考Jquery Ajax dataType)

曾經嘗試Ajax回傳檔案

Ajax回傳進入error區塊,於Network的Response出現以下文字畫面,右鍵點選open in new tab 則可下載檔案


解決方法】:

StackOverflow上有一篇Recieving a Zip file as response on AJAX request文章討論到這種問題的解法,大致上就是用a標籤的新屬性(download)來進行,或是使用window.open()另開一個視窗來觸發。

方法一 window.open()

語法:window.open(‘ 新視窗的網址 ‘, ‘新視窗的名稱’, config=’height=高度,width=寬度’);

範例:

//無參數:
let url="/XXX/query";
let fillName=encodeURL('測試下載');
window.open( url  ,  fillName  ,  'width='+100+',height='+600);
--------------------
//有參數:
let url="/XXX/query";
let fillName=encodeURL('測試下載');
window.open( url+'?type=pdf&name='+123  ,  fillName  ,  'width='+100+',height='+600);

方法二 Form表單提交下載檔案

當有多個參數卻因URL限制長度,可使用form.submit 提交

範例:

function click(){
    //參數
    var params = {
        id:xx,
        name:xx
    };

    //在畫面建立一個form表單出來
    var form = document.createElement('form');
    form.id = 'form';
    form.name = 'form';
    document.body.appendChild (form);

    //將參數依依放入form裡面
    for (var obj in params) {
        if (params.hasOwnProperty(obj)) {
            var input = document.createElement('input')
            input.tpye='hidden'
            input.name = obj;
            input.value = params[obj]
            form.appendChild(input)
        }
    }

    form.method = "GET" //請求方式
    form.action = "/XXX/query"
    form.submit();
    document.body.removeChild(form);//清除畫面form表單
},

回傳檔案常見異常】

  1. 常見異常:No converter for XXX with preset Content-Type ‘application/octet-stream
  2. form.submit()出現302,解決方法為於參數加入token

Related Posts

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js