js中如何使用ajax的get来向后台获取文件流进行文件下载(其中header中传token参数)

js中如何使用ajax的get来向后台获取文件流进行文件另存为的下载

其中header需要传token和os参数到后台进行验证

请问这个JS应该如何写?希望大神不吝赐教,谢谢~

如下方法后台无法获取header参数,360浏览器中也没有启动另存为的窗口

var url = "{#$apiHost#}/aw/export?brand_ids="+brand_ids;
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = "blob";
xhr.setRequestHeader("token", "5f963175cc75613398e25ce2e5da56d7");
xhr.setRequestHeader("os", "1");
xhr.onload = function() {
    if (this.status == 200) {
        try{
            var elemIF = document.createElement("iframe");
            elemIF.src = this.responseURL;
            elemIF.style.display = "none";
            document.body.appendChild(elemIF);
        }catch(e){
        }
    }
}
xhr.send();
阅读 10.7k
3 个回答

改成这样就好了。

var xhh = new XMLHttpRequest();
                xhh.open("post", Action.FILES_W_DOWNLOADFILE + "/"+ fileName );
                xhh.setRequestHeader("Authorization", this.Axios.defaults.headers.Authorization = JSON.parse(getCookie('userInfo')).tokenType+ ' ' + JSON.parse(getCookie('userInfo')).accessToken);
                xhh.setRequestHeader("Content-Type","application/json");
                xhh.responseType = 'blob';
                xhh.onreadystatechange = function () {
                    if (xhh.readyState === 4 && xhh.status === 200) {
                        var name = xhh.getResponseHeader("ajax-filename");
                        var mimeType = xhh.getResponseHeader("ajax-mimeType");
                        var blob = new Blob([xhh.response], {type: mimeType});
                        var csvUrl = URL.createObjectURL(blob);
                        var link = document.createElement('a');
                        document.body.appendChild(link); //创建的标签添加到body,解决Firefox下无法打开页面的问题
                        link.href = csvUrl;
                        link.target = '_blank';
                        link.id = 'linkId',
                        link.className = 'linkId',
                        link.download = decodeURI(name);
                        document.getElementById("linkId").click();
                        // link.remove(); //将a标签移除
                        $('.linkId').remove()
                    }
                };
                xhh.send();

在浏览器环境下,JS不具备对本地文件进行完全可控的读写能力。因此,如果可以的话,尽量让后台从GET的参数中获取token等信息,然后返回文件流。前端只需要使用 a 标签和 download 属性即可下载。


如果一定要从前端读取文件流然后下载,可以使用 blob 对象实现。但是兼容性就无法保证了,blob对象只在 IE11 可用。

另外后台收不到 header 可能是跨域问题导致的,只要是带自定义header的跨域请求,在发送真实请求前都会先发送OPTIONS请求,浏览器根据OPTIONS请求返回的结果来决定是否继续发送真实的请求进行跨域资源访问。

function export_raw(name, blob) {
    // name=文件名, blob=文件二进制对象
    var urlObject = window.URL || window.webkitURL || window;
    var save_link = document.createElementNS("http://www.w3.org/1999/xhtml", "a")
    save_link.href = urlObject.createObjectURL(blob);
    save_link.download = name;
    fake_click(save_link);
}

function fake_click(obj) {
    var ev = document.createEvent("MouseEvents");
    ev.initMouseEvent(
        "click", true, false, window, 0, 0, 0, 0, 0
        , false, false, false, false, 0, null
    );
    obj.dispatchEvent(ev);
}

经过网上查阅资料,成功将header传到了后台,
现在的问题是,后台给我返回了文件流,请问使用JS如何去自动下载这个返回的文件流

var settings = {
  "async": true,
  "crossDomain": true,
  "url": "{#$apiHost#}/aw/export?brand_ids="+brand_ids,
  "method": "GET",
  "headers": {"token": "5f963175cc75613398e25ce2e5da56d7","os": "1"}
}
$.ajax(settings).done(function (data) {
    console.log(data);
});

以上data就是返回的文件流,请问如何正确使用JS来让返回的文件流自动下载呢?

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题