的javascript-window.onload没有被触发

时间:2019-01-29 11:12:55

标签: javascript jquery web

我想做的是一个将导出pdf文件的工具。

有两种情况:

  1. 我无需检查任何内容,并且在用户单击导出按钮后,它将立即打开一个新的空白窗口,因为我使用标题下载文件,并且在空白页加载完成后,它将关闭。

案例1的脚本

$('body').on("click", '.export-invoice-pdf', function () {
    // get id
    let id = $(this).closest('tr').data('id');
    let newWindow = window.open(
        'url' + id,
        "_blank"
    );
    newWindow.onload = function() {
        newWindow.close();
    };
});

这很好


  1. 我必须检查条目是否有可用的pdf文件。在打开一个新的空白窗口以保存文件之前,然后像在case1中一样关闭它

情况2的脚本

$('body').on("click", '.export-invoice-pdf', function () {
    // get id
    let id = $(this).closest('tr').data('id');
    let newWindow = window.open(
        '',
        "_blank"
    );
    //Ajax call to check if there is an available file
    $.ajax({
        type: 'POST',
        url: 'url',
        data: {'orderId': orderId},
        dataType: 'json',
        encode: true,
    }).success(function (data) {
        console.log('1');
        if (data.hasFile === true) {
            //if has file do the samething as case 1
            newWindow.location.href = 'url' + orderId;
            newWindow.onload = function() {
                 newWindow.close();
            };
        } else {
            alert('no file to export');
        }
    }).error(function () {
    });
});

现在这不起作用。实际上,我的第一个问题是没有创建新窗口,因为它将新窗口视为弹出窗口,但是经过一个小时的研究,我将其修复了。现在关闭窗口是我的问题。

我已经在其中查找了它,但目前仍然不仅在这里查找,而且很遗憾,我无法找到有关此问题的答案。任何帮助都将受到赞赏。


更新:对我有用的是使用XMLHttpRequest,这样我就不必打开新的空白标签,这样我的php标头即可为我提供PDF文件。

这是我正在使用的代码:

    let xhr = new XMLHttpRequest();

    //we use responseType arraybuffer so that the pdf file won't be blank
    xhr.open('GET', url);
    xhr.responseType = 'arraybuffer';
    xhr.onload = function(e) {
        if (this.status === 200) {
            var blob = new Blob([this.response], {type:"application/pdf"});
            var link = document.createElement('a');
            link.href = window.URL.createObjectURL(blob);
            link.download = "nameofpdf.pdf";
            link.click();
        }
    };
    xhr.send();

我使用的url是由控制器处理的,该控制器仍然使用php标头为我提供了pdf文件。

3 个答案:

答案 0 :(得分:0)

尝试一下?

$('body').on("click", '.export-invoice-pdf', function () {
    //Ajax call to check if there is an available file
    $.ajax({
        type: 'POST',
        url: 'url',
        data: {'orderId': orderId},
        dataType: 'json',
        encode: true,
    }).success(function (data) {
        console.log('1');
        if (data.hasFile === true) {
            //if has file do the samething as case 1
            // get id
            const id = $(this).closest('tr').data('id');
            Object.assign(document.createElement('a'), {
                target: '_blank',
                'url' + orderId,
            }).click();
            // make user close the tab
        } else {
            alert('no file to export');
        }
    }).error(function () {
    });
});

答案 1 :(得分:0)

如果window.open()未被直接用户操作调用,弹出窗口阻止程序通常不允许弹出窗口(或以编程方式单击动态创建的超链接等)。每个浏览器的阻止弹出窗口的机制都略有不同。

在您的情况1中,由于用户单击了导出按钮,因此所有代码都首先在主线程上运行。效果很好。

在情况2中打开窗口可能无法在所有浏览器中正常工作,因为它是从另一个线程调用的。在您的onclick事件结束很长时间之后,将异步调用Ajax成功处理程序。

要纠正此问题,可以使用同步请求在主线程上执行所有代码。 您可以XMLHttpRequest或异步选项$.ajax({async: false})。这样可以确保您的代码在所有浏览器更改弹出窗口阻止算法时都可以使用。

实施以上建议可以在不触发window.onload()的情况下帮助解决您的问题,但是还有另一项改进-在导航之前添加onload处理程序:

//if has file do the samething as case 1
newWindow.onload = function() {
     newWindow.close();
};
newWindow.location.href = 'url' + orderId;

或者甚至更好地将其添加到主线程中,紧随其后

let newWindow = window.open(
    '',
    "_blank"
);
newWindow.onload = function() {
     newWindow.close();
};

希望,它会有所帮助。

答案 2 :(得分:0)

考虑为此使用iframe。这是一个非常有效的解决方案,可以避免监听另一个窗口事件,这是一种不好的做法,不需要这样做。

function downloadFile(fileUrl) {
        var downloadIframe = $('#download-iframe');
        if (downloadIframe) {
              downloadIframe.remove();
        }
        $('<iframe>', {
            id: 'download-iframe',
            src: fileURL
        }).hide().appendTo('body');
}