JQuery处理blob类型的Response的问题

在一个ASP.NET Core MVC的控制器中,根据条件,可能返回一个Excel的文件流,也可能返回一个Json的错误信息,代码类似如下:

if(templeteId == null)
{
	return Json(new {success = false, msg = "没有指定模板"});
}
else 
{
	//生成文件流的代码略,stream是文件流,fileName是文件名
	return File(stream.GetBuffer(), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", $"{fileName}.xlsx");
}

在前端,我用jquery的ajax访问后台

$.ajax({
    url: "@Url.Action("GenerateReport")",
    data: {taskId: taskId, linePointId: linePointId},
    dataType: "blob",
    type: "get",
    success: (result,status,xhr) => {
        console.log(result)
    },
    error: (xhr,status,error) => {
        console.log(error)
    }
})

不管是返回json还是文件流,控制台的输出都是No conversion from text to blob
我一度以为是我的后台问题,我甚至把返回Json的代码改成这样:

var json = "{\"success\": false, \"msg\": \"没有模板文件\"}";
return File(Encoding.UTF8.GetBytes(json), "text/plain");

结果还是一样。
我把前端代码中的dataType: "blob"删掉,调用倒是没问题了,但不管是文件流还是json,返回的形式都变成了Text。
我在ajax函数的success回调中打印xhr对象,才发现jquery封装的这个xhr对象,只提供了responseText属性,而原始的XMLHttpRequest中的response属性并没有提供给我们。
百度了一下,发现网上成功处理我这种后台返回类型的都是用的axios,但我并不想因为一个ajax的调用又引入一个js库。
最终只能用XMLHttpRequest对象完成。

function exportReport(taskId, linePointId){
    var xhr = new XMLHttpRequest();
    xhr.open("get", `@Url.Action("GenerateReport")?taskId=${taskId}&linePointId=${linePointId}`, true);
    xhr.responseType = "blob";
    xhr.onreadystatechange = () => {
        if(xhr.readyState == 4 && xhr.status == 200) {
            let contentType = xhr.getResponseHeader("content-type");
            let blob = new Blob([xhr.response]);
            if(contentType.includes("application/json")) {
                blob.text().then(text => {
                    let json = JSON.parse(text);
                    layer.msg(json.msg);
                });
            } else {
                let disposition = xhr.getResponseHeader("content-disposition");
                let fileName;
                if(disposition.includes("filename*")) {
                    //如果包含filename*,则以该字段内容为文件名,并对文件名进行解码
                    fileName = disposition.split(';')[2].split('=')[1];
                    fileName = fileName.substring(fileName.lastIndexOf("'") + 1);
                    fileName = urlDecode(fileName);
                } else {
                    fileName = disposition.split(';')[1].split('=')[1];
                }
                let url = window.URL.createObjectURL(blob);
                let a = document.createElement("a");
                a.href = url;
                a.download = fileName;
                a.click();
                window.URL.revokeObjectURL(url);
            }
        }
    }
    xhr.send();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值