第一种 Ajax:后台返回bufferArray ,如果前端req.responseType='blob'未指定后端返回File()类型的时候默认按照字节数组arraybuffer 返回前端需要前端转为Blob对象

// 点击下载按钮时触发
$("#download-btn").click(function() {
  // 发送 AJAX 请求获取字节数组
   $.ajax({
            url: url,
            type: "GET",
            xhrFields: { responseType: "blob" },
            success: function (response, status) {
            
                var blob = new Blob([response], { type: "application/pdf" });// 此转换为xhrFields: { responseType: "arraybuffer" },
                
                var link = document.createElement("a");
                link.href = window.URL.createObjectURL(response);
                link.download = "example.pdf";
                document.body.appendChild(link);
                link.click();
            },
            error: function (xhr, status, error) {
                console.log("Error:", error);
            }
        });
});

      

后端代码:

 Response.Headers.Add("fileName", fileExtensionName);
 Response.Buffer = false;
 var bytes = new byte[renderingResult.DocumentBytes.Length];
 renderingResult.DocumentBytes.CopyTo(bytes, 0);
//return File(bytes, System.Net.Mime.MediaTypeNames.Application.Octet, fileExtensionName);
 return File(renderingResult.DocumentBytes, renderingResult.MimeType, fileExtensionName);nsionName);

第二种使用XmlHttpRequest对象

下面 req.responseType = "blob"; 设置成这样后,window.URL.createObjectURL(req.response); 直接使用不需要进行Blob转换

      var req = new XMLHttpRequest();
        req.open("GET", url, true);
        req.responseType = "blob";
        req.onloadstart = function (e) {
            console.log('e.onloadstartloaded', e.loaded)
        }
        req.onprogress = function (e) {
            var pb = $("#progressBar").data("kendoProgressBar");
            var prog = $("#progressBarLoad");

            console.log('e.loaded', e.loaded)
            console.log('e.total', e.total)
            //if (e.lengthComputable) {
            //    pb.value(Math.round(e.loaded * 100 / e.total));
            //    prog.text('done');
            //} else {
            //    prog.text(loaded);
            //}
 
        } //下载监听
        req.onload = function (oEvent) {
            if (req.status === 200) {
                var blob = req.response;
                var blobData = new Blob([req.response]);
                var fileName = req.getResponseHeader("fileName")
                if (fileName) {
                    var link = document.createElement('a');
                    link.href = window.URL.createObjectURL(req.response);
                    link.download = fileName;
                    link.click();
                    link.remove();
                    window.URL.revokeObjectURL(link.href);
                } else {
                    location.reload();
                }
                //kendo.ui.progress(ele, false);
            } else {
                console.log('error')
                kendo.ui.progress(ele, false);
            }
        };
        req.onloadend = function (e) {
            //$("#progressBar").hide();
            $("#progressBarLoad").text('done');
        }
        req.send();

如果出现以下报错

检查后端Response.Buffer 值,资源文件一版过大在服务端会缓存一次性响应到前端就会导致blob在req.send() 的时候报错,XMLHttpRequest 的status=0 而不是200

解决办法 1.

Response.Buffer = false;

说明:Response.Buffer = false; 则可以进行分片下载及需要设置进度条的下载方式

ASP.NET中,Response.Buffer是用于指定是否在服务器上缓存输出内容的属性。如果将其设置为true,则服务器将整个响应缓存在内存中,直到服务器端代码执行完毕,并将整个响应一次性发送给客户端。这样可以提高性能,减少网络流量和延迟。但是,对于大型文件或长时间运行的操作,可能会导致服务器资源不足。

如果将Response.Buffer设置为false,则服务器将逐步将输出内容发送到客户端,而不必等待整个响应完全生成。这种方法可以更快地开始发送响应,并减少服务器使用的内存数量。但是,它可能会导致响应变慢或分段传输,导致用户体验下降。

在ASP.NET MVC中,默认情况下,Response.Buffer已经设置为true,因此在大多数情况下,您不需要显式设置它。

解决办法2:

后端代码 下面的buffer=true或者false不会影响前端接受blob

   var bytes = new byte[renderingResult.DocumentBytes.Length];
            renderingResult.DocumentBytes.CopyTo(bytes, 0);

            Response.Clear();
            Response.ContentType = renderingResult.MimeType;
            Response.Cache.SetCacheability(HttpCacheability.Private);
            Response.Expires = -1;
            Response.Buffer = true;
            Response.BinaryWrite(renderingResult.DocumentBytes);
            Response.Flush();
            Response.End();
            return string.Empty; ;
            //return File(bytes, renderingResult.MimeType);

更多推荐