常见Ajax下载文件方式以及报错解决办法
作者:andy5520
第一种 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);
总结
到此这篇关于常见Ajax下载文件方式以及报错解决办法的文章就介绍到这了,更多相关Ajax下载文件及报错内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!