通过使用JAX-RS以及Ajax和JavaScript的blob对象下载文件,无法正常工作 [英] Downloading file by using JAX-RS together with ajax and javascript's blob object, doesn't work

查看:1814
本文介绍了通过使用JAX-RS以及Ajax和JavaScript的blob对象下载文件,无法正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试使用 JavaScript的Blob对象下载文件,但奇怪的事情正在发生。 首先我使用 JAX-RS 发送从后端的文件,这是我的code:

 工作簿WB =新HSSFWorkbook();

    //创建工作簿...

    ByteArrayOutputStream BOS =新ByteArrayOutputStream();
    尝试 {
        wb.write(BOS);
        bos.close();
    }赶上(例外五){
        e.printStackTrace();
    }
    字节[]字节= bos.toByteArray();
    返回Response.ok(字节).header(内容处置,附件;文件名=+TEST.XLS)。建();
 

BOS 是我从的Apache POI 工作簿中创建ByteArrayOutputStream对象。如果使用常规的方法来下载这个文件,即指向浏览器中的 JAX-RS 的资源,一切正常,但是当我尝试使用这一解决方案的http://stackoverflow.com/a/23797348/947111 中这是行不通的,下载文件损坏。

当我试图在Chrome的控制台我关注的有响应对象和斑点当我试图转换响应<对象/之间的尺寸差进行调试STRONG>为斑点。在响应大小是4096字节,

 时间:星期二,2015年2月10号17点32分27秒格林尼治标准​​时间
服务器:WildFly / 8
连接:保持活动
的X已启动方式:暗潮/ 1
内容长度:4096
内容处置:附件;文件名= TEST.XLS
内容类型:应用程序/ vnd.ms-Excel中
 

但是,当我执行 VAR一滴=新的斑点([回应] {型:}); BLOB 成为大小7836字节,即当我在控制台执行 blob.size ,我得到这个尺寸。下载文件的大小为7834字节。但是,当我停止调试器在这一点上 VAR downloadUrl = URL.createObjectURL(BLOB); 键,点浏览器的另一个选项卡 downloadURL ,下载的文件的大小似乎是7836字节,并且似乎已损坏了。 所以,我的问题是,为什么它不工作,为什么有大小的区别? 我使用 Chrome浏览器版本40.0.2214.111(64位),但在火狐35.0.1 我有一个相同的行为。

感谢你在前进。

P.S。我的客户端从满code <一个href="http://stackoverflow.com/questions/16086162/handle-file-download-from-ajax-post/23797348#23797348">SO问题我上面提到的:

  $。阿贾克斯({
    键入:POST,
    网址:网址,
    数据:参数,可以
    成功:函数(响应状态,XHR){
        //检查文件名
        VAR文件名=;
        无功配置= xhr.getResponseHeader(内容处置');
        如果(处置和放大器;&安培; disposition.indexOf('附件')== -1!){
            VAR filenameRegex ​​= /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
            VAR匹配= filenameRegex.exec(处置);
            如果(匹配=空&安培;!&安培;火柴[1])的文件名=火柴[1] .replace(/ ['] /克,'');
        }

        VAR类型= xhr.getResponseHeader(Content-Type的');
        VAR BLOB =新的斑点([回应] {型:});

        如果(typeof运算window.navigator.msSaveBlob!==未定义){
            // IE的解决方法HTML7007:一个或一个以上的blob的网址被关闭,他们创立的BLOB撤销这些URL将不再解析为后盾的URL中的数据已被释放
            window.navigator.msSaveBlob(BLOB,文件名);
        } 其他 {
            VAR URL = window.URL || window.webkitUR​​L;
            VAR downloadUrl = URL.createObjectURL(BLOB);

            如果(文件名){
                //使用HTML5一个[下载]属性来指定文件名
                变种一个= document.createElement方法(一);
                // Safari浏览器不支持此尚未
                如果(typeof运算a.download ===未定义){
                    了window.location = downloadUrl;
                } 其他 {
                    a.href = downloadUrl;
                    a.download =文件名;
                    document.body.appendChild(一);
                    a.click();
                }
            } 其他 {
                了window.location = downloadUrl;
            }

            的setTimeout(函数(){URL.revokeObjectURL(downloadUrl);},100); // 清理
        }
    }
});
 

解决方案

您的二进制数据转换为文本,这破坏你的数据。
目前jQuery.Ajax不能做一个类型的Ajax请求,这是你所需要的,因此,你将不得不使用裸XMLHtt prequest和设置的 responseType BLOB 然后 XMLHtt prequest.response 将数据作为BLOB

I trying to download file by using javascript's Blob object, but something weird is happening. First of all I use JAX-RS to send the file from backend, this is my code:

    Workbook wb = new HSSFWorkbook();

    //creating workbook...

    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    try {
        wb.write(bos);
        bos.close();
    } catch(Exception e) {
        e.printStackTrace();
    }
    byte[] bytes = bos.toByteArray();
    return Response.ok(bytes).header("Content-Disposition", "attachment; filename=" + "test.xls").build();

bos is 'ByteArrayOutputStream' object which I create from Apache POI workbook. If I use regular way to download this file, i.e. pointing browser to JAX-RS resource, everything works fine, but when I try to use this solution http://stackoverflow.com/a/23797348/947111 it doesn't work, file being downloaded corrupted.

When I tried to debug it in Chrome's console I paid attention that there's difference in size between response object and Blob object when I trying convert response to Blob. Size of the response is 4096 bytes,

Date: Tue, 10 Feb 2015 17:32:27 GMT
Server: WildFly/8
Connection: keep-alive
X-Powered-By: Undertow/1
Content-Length: 4096
Content-Disposition: attachment; filename=test.xls
Content-Type: application/vnd.ms-excel

But when I perform var blob = new Blob([response], { type: type });, blob becomes the size of 7836 bytes, i.e. when I perform blob.size in console, I get this size. Downloaded file's size is 7834 bytes. But when I stop debugger at this point var downloadUrl = URL.createObjectURL(blob); and point browser in another tab to downloadURL, downloaded file's size appear to be 7836 bytes, and appears to be corrupted too. So, my question is why it doesn't work and why there's difference in size? I use Chrome Version 40.0.2214.111 (64-bit), but in Firefox 35.0.1 I have a same behaviour.

Thank you in advance.

P.S. The full code of my client side from SO question which I mentioned above:

$.ajax({
    type: "POST",
    url: url,
    data: params,
    success: function(response, status, xhr) {
        // check for a filename
        var filename = "";
        var disposition = xhr.getResponseHeader('Content-Disposition');
        if (disposition && disposition.indexOf('attachment') !== -1) {
            var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
            var matches = filenameRegex.exec(disposition);
            if (matches != null && matches[1]) filename = matches[1].replace(/['"]/g, '');
        }

        var type = xhr.getResponseHeader('Content-Type');
        var blob = new Blob([response], { type: type });

        if (typeof window.navigator.msSaveBlob !== 'undefined') {
            // IE workaround for "HTML7007: One or more blob URLs were revoked by closing the blob for which they were created. These URLs will no longer resolve as the data backing the URL has been freed."
            window.navigator.msSaveBlob(blob, filename);
        } else {
            var URL = window.URL || window.webkitURL;
            var downloadUrl = URL.createObjectURL(blob);

            if (filename) {
                // use HTML5 a[download] attribute to specify filename
                var a = document.createElement("a");
                // safari doesn't support this yet
                if (typeof a.download === 'undefined') {
                    window.location = downloadUrl;
                } else {
                    a.href = downloadUrl;
                    a.download = filename;
                    document.body.appendChild(a);
                    a.click();
                }
            } else {
                window.location = downloadUrl;
            }

            setTimeout(function () { URL.revokeObjectURL(downloadUrl); }, 100); // cleanup
        }
    }
});

解决方案

Your binary data is converted to text, this corrupts your data.
Currently jQuery.Ajax cannot do a typed ajax request, which is what you need, therefore you'll have to use bare XMLHttpRequest and set the responseType to blob then XMLHttpRequest.response will be the data as a blob

这篇关于通过使用JAX-RS以及Ajax和JavaScript的blob对象下载文件,无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆