为什么从一个ASP.NET下载(AJAX下载与斑点)时,有文件是不同的 [英] Why are files are different when downloading from an ASP.NET (AJAX download with Blob)

查看:171
本文介绍了为什么从一个ASP.NET下载(AJAX下载与斑点)时,有文件是不同的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用MVC 4.0,我使用了下列code从一个AJAX源创建从服务器下载文件(使用最新的Firefox):

这工作正常,如果输出涉及的文本文件,如CSV或TXT文件,但是,当涉及到像zip文件或XLSX,看来下载的文件是从原始来源不同(在IE浏览器的压缩产生的服务器是15K,但一下载的是26K)

我一直在挣扎了几天,我可以问,如果有人要切丝为什么会作品CSV /文本文件,而不是压缩或XLSX文件的一些轻?

感谢

控制器:

 公共功能下载(DATAIN作为myObject的)作为的ActionResult
        一些处理
        生成的压缩文件,并返回的完整路径
        昏暗zipFullPath = generateFiles(DATAIN)

        Response.Clear()
        Response.ContentType =应用程序/压缩
        Response.AddHeader(内容处置,附件;文件名= Out.zip)
        暗淡文件长度=新IO.FileInfo(zipFullPath).Length
        文件长度读取有关15K数据
        Response.AddHeader(内容长度,文件长度)
        Response.TransmitFile(zipFullPath)
        到Response.End()
        返回查看()
    端功能
 

JavaScript的:

  $。阿贾克斯({
    键入:POST,
    网址:报告/下载,
    数据:jData,
    的contentType:应用/ JSON的;字符集= UTF-8,
    成功:函数(响应状态,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();

                    //这是问题所在,原来是约15K,
                    //但下载文件大约是26K

                }
            } 其他 {
                了window.location = downloadUrl;
            }

            的setTimeout(函数(){URL.revokeObjectURL(downloadUrl);},100); // 清理
        }
    },
    错误:功能(数据){
        警报(错误);
    }
});
 

解决方案

目前jQuery的阿贾克斯只能处理文本的反应,这就是为什么你的文本文件,但您的二进制文件失败。
从阿贾克斯下载一个非文本文件,使用XMLHtt prequest对象,并指定一个responseType,例如 BLOB arraybuffer

  VAR XHR =新XMLHtt prequest();
xhr.onreadystatechange =功能(){
    如果(this.readyState == 4和&安培; this.status == 200){
        ...
        VAR BLOB = this.response; //保存BLOB像往常一样
        ...
    }
}
xhr.open(POST,报告/下载);
xhr.setRequestHeader(内容类型,应用/ JSON的;字符集= UTF-8);
xhr.responseType ='一滴'; //响应将是一个blob,而不是文本
xhr.send(jData);
 

Using MVC 4.0, I have used the following code to create a download files from the server from an ajax source (using the latest firefox):

This works fine if the output involves are textual files such as csv or txt files, however, when it comes to files like zip or xlsx, it seems the downloaded file is different from the original source (i.e. the zip generated within the server are 15K, but the one downloaded are 26K)

I have been struggling for a few days, can I ask if anyone should shred some light on why it will works for csv/text files, but not for zip or xlsx files?

Many thanks

Controller:

Public Function download(dataIn As myObject) As ActionResult
        'some processing
        'generated zip files and return with the full path            
        Dim zipFullPath = generateFiles(dataIn)

        Response.Clear()
        Response.ContentType = "application/zip"           
        Response.AddHeader("Content-Disposition", "attachment; filename=Out.zip")
        Dim fileLength = New IO.FileInfo(zipFullPath).Length
        'fileLength  reads about 15K of data
        Response.AddHeader("Content-Length", fileLength)
        Response.TransmitFile(zipFullPath)
        Response.End()
        Return View()
    End Function

JavaScript:

$.ajax({
    type: "POST",
    url: "reports/download",
    data: jData,
    contentType: "application/json; charset=utf-8",
    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();

                    //Here is the problem, the original is about 15k,  
                    // but the download file is about 26K

                }
            } else {                    
                window.location = downloadUrl;
            }

            setTimeout(function () { URL.revokeObjectURL(downloadUrl); }, 100); // cleanup
        }
    },
    error: function (data) {
        alert('Error');
    }
});

解决方案

Currently jQuery ajax can only process text responses, that's why your text files work but your binary files fail.
To download a non text file from ajax use the XMLHttpRequest object and specify a responseType, for instance blob or arraybuffer.

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
    if (this.readyState == 4 && this.status == 200){
        ...
        var blob = this.response; //save the blob as usual
        ...
    }
}
xhr.open('POST', 'reports/download');
xhr.setRequestHeader('Content-Type', 'application/json; charset=utf-8');
xhr.responseType = 'blob'; // the response will be a blob and not text
xhr.send(jData);      

这篇关于为什么从一个ASP.NET下载(AJAX下载与斑点)时,有文件是不同的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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