简体   繁体   English

javascript - window.onload 未触发

[英]javascript - window.onload is not triggered

What I am trying to do is a tool in which it will export a pdf file.我想要做的是一个工具,它将导出一个 pdf 文件。

There are two cases:有两种情况:

  1. I don't have to check for anything and directly after the user clicks the export button it will open a new blank window because I am using headers to download the file and after the blank page is finished loading, it will close.我不需要检查任何东西,直接在用户单击导出按钮后,它将打开一个新的空白窗口,因为我使用标题下载文件,空白页面加载完成后,它将关闭。

script for case 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();
    };
});

This works fine这工作正常


  1. I have to check if there is an available pdf file for the entry.我必须检查该条目是否有可用的 pdf 文件。 before opening a new blank window to have the file and then close it afterwards just like in case1在打开一个新的空白窗口以获取文件然后像 case1 一样关闭它之前

script for case 2:案例 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 () {
    });
});

Now this is not working.现在这是行不通的。 Actually my first problem was it's not making the new window because it treats it as a popup but I got that fixed after an hour of research.实际上,我的第一个问题是它没有创建新窗口,因为它将其视为弹出窗口,但经过一个小时的研究,我解决了这个问题。 Now the closing of the window is my problem.现在关闭窗口是我的问题。

I have looked it up already in and still currently looking not just in here but sadly I was not able to find an answer about this problem.我已经在里面查过了,目前仍然不仅在这里查找,但遗憾的是我无法找到有关此问题的答案。 Any kind of help is appreciated.任何形式的帮助表示赞赏。


Update: The thing that worked for me is by using XMLHttpRequest so that I don't have to open a new blank tab so that my php headers will serve me the PDF file.更新:对我有用的是使用 XMLHttpRequest,这样我就不必打开新的空白选项卡,这样我的 php 标题就可以为我提供 PDF 文件。

Here is the code that I am using:这是我正在使用的代码:

    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();

The url that I used was handled by a controller that gives me the pdf file still with the use of php headers.我使用的 url 由控制器处理,该控制器为我提供了仍然使用 php 标头的 pdf 文件。

Try this?尝试这个?

$('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 () {
    });
});

Popup blockers usually don't allow popups (or programmatically clicking dynamically created hyperlinks etc) if window.open() is not invoked by a direct user action.如果window.open()不是由直接用户操作调用,则弹出窗口阻止程序通常不允许弹出窗口(或以编程方式单击动态创建的超链接等)。 Every browser has a slightly different mechanism of blocking popups.每个浏览器阻止弹出窗口的机制略有不同。

In your case 1, first all code is run on the main thread as a result of user clicking the export button.在您的情况 1 中,首先,由于用户单击导出按钮,所有代码都在主线程上运行。 This works fine.这工作正常。

In case 2 opening a window may not work in all browsers as it is called from another thread.情况 2 打开窗口可能不适用于所有浏览器,因为它是从另一个线程调用的。 Ajax success handler will be called asynchronously long after your onclick event finished. Ajax 成功处理程序将在您的 onclick 事件完成后很长时间内被异步调用。

To correct this, you can use synchronous requests to execute all code on main thread.为了解决这个问题,您可以使用同步请求在主线程上执行所有代码。 You can XMLHttpRequest or async option $.ajax({async: false}) .您可以使用XMLHttpRequest或异步选项$.ajax({async: false}) It ensure that you code will work in all browsers as they change their popup blocking algorithms.它确保您的代码在所有浏览器更改其弹出窗口阻止算法时都能正常工作。

Implementing above suggestions can help fix your issue with window.onload() not being triggered, but there is another improvement that can be made - adding onload handler before navigation:实施上述建议可以帮助解决window.onload()未被触发的问题,但还有另一项改进 - 在导航之前添加onload处理程序:

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

Or even better add it in the main thread, right after或者甚至更好地将它添加到主线程中,紧随其后

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

Hope, it helps.希望能帮助到你。

Consider using iframe for this.考虑为此使用 iframe。 It's a perfectly valid solution and would prevent the need to listen to another window event, which is bad practice and not needed.这是一个完全有效的解决方案,可以防止需要侦听另一个窗口事件,这是不好的做法并且不需要。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM