简体   繁体   中英

javascript - window.onload is not triggered

What I am trying to do is a tool in which it will export a pdf file.

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

$('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. before opening a new blank window to have the file and then close it afterwards just like in case1

script for case 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.

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.

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. 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. This works fine.

In case 2 opening a window may not work in all browsers as it is called from another thread. Ajax success handler will be called asynchronously long after your onclick event finished.

To correct this, you can use synchronous requests to execute all code on main thread. You can XMLHttpRequest or async option $.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:

//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. 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');
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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