You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel+Maatwebsite中Ajax响应无法自动触发Excel下载问题

问题场景

页面截图
实现复选框勾选批量导出Excel功能时,使用Ajax发起请求可以正常获取后端返回数据,但无法自动触发Excel文件下载,手动在新标签页打开对应请求URL可正常下载文件。
网络请求截图

现有前端代码

$(document).on('click', '#selectAll', function() {
    $(".order").prop("checked", this.checked);
    var total = $("input.order:checked").length + " Orders Selected";
    $('#selected').html(total);
});
$(document).on('click', '.order', function() {
    if ($('.order:checked').length == $('.order').length) {
        $('#selectAll').prop('checked', true);
    } else {
        $('#selectAll').prop('checked', false);
    }
    var total_single = $("input.order:checked").length + " Orders Selected";
    $('#selected').html(total_single);
});

$(document).ready(function() {
    $('#export_records').on('click', function(e) {
        e.preventDefault();
        var orders = [];
        $(".order:checked").each(function(){
            orders.push($(this).val());
        });
        if (orders.length <= 0) {
            alert("Please select records.");
        } else {
            var selected_values = orders;
            $.ajax({
                type: "GET",
                url: "{{route('mfiint_export_bulk')}}",
                cache: false,
                data: {'orders':selected_values,"_token":"{{ csrf_token() }}"}, 
                success:function(data){
                    // 此处编写的自动下载逻辑无法生效
                }
            });
        }
    });
});

现有后端代码

控制器导出响应逻辑:

return Excel::download(new mfiintBulkExport($purchases_bulk),'bulkorders.xlsx');

导出类实现代码:

public function __construct($purchases_bulk)
{
    $this->purchases_bulk = $purchases_bulk;
}

public function view(): View
{
    return view('mfiint.bulk_orderexport',['purchases_bulk'=>$this->purchases_bulk]);
}
问题原因

普通Ajax请求接收的是二进制文件流,浏览器不会自动识别这类响应触发默认下载行为。在success回调中直接处理二进制流的方案兼容性差、实现冗余,文件下载场景本身就不适合用普通Ajax发起请求。

解决方案

推荐方案:动态构造表单提交(兼容性最好)

不需要走Ajax请求,动态创建隐藏表单提交参数,浏览器会自动识别文件响应触发下载,兼容所有主流浏览器,代码简洁稳定。
替换原有Ajax部分的逻辑即可:

$('#export_records').on('click', function(e) {
    e.preventDefault();
    var orders = [];
    $(".order:checked").each(function(){
        orders.push($(this).val());
    });
    if (orders.length <= 0) {
        alert("Please select records.");
        return false;
    }
    // 动态创建提交表单
    var downloadForm = $('<form action="{{route('mfiint_export_bulk')}}" method="GET" target="_blank"></form>');
    // 加入CSRF校验参数
    downloadForm.append('<input type="hidden" name="_token" value="{{ csrf_token() }}">');
    // 加入所有选中的订单ID
    orders.forEach(function(orderId){
        downloadForm.append('<input type="hidden" name="orders[]" value="'+orderId+'">');
    });
    // 临时挂载表单触发提交,提交完成后移除表单
    downloadForm.appendTo('body').submit().remove();
});

备选方案:Ajax+Blob实现(需指定响应类型)

如果必须使用Ajax实现,需要在请求配置中声明响应类型为二进制Blob,拿到响应后创建临时a标签触发下载:

$.ajax({
    type: "GET",
    url: "{{route('mfiint_export_bulk')}}",
    cache: false,
    // 必须指定响应类型为blob
    xhrFields: {
        responseType: 'blob'
    },
    data: {'orders':selected_values,"_token":"{{ csrf_token() }}"}, 
    success:function(blobData){
        // 生成Blob临时地址
        var blobUrl = window.URL.createObjectURL(blobData);
        // 创建临时a标签触发下载
        var tempLink = document.createElement('a');
        tempLink.href = blobUrl;
        tempLink.download = 'bulkorders.xlsx';
        document.body.appendChild(tempLink);
        tempLink.click();
        // 释放资源,移除临时元素
        document.body.removeChild(tempLink);
        window.URL.revokeObjectURL(blobUrl);
    }
});

注意:Blob方案在部分低版本浏览器存在兼容问题,无特殊需求优先选择动态表单方案。

内容的提问来源于stack exchange,提问作者Mannu254

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 20:21:28