【问题标题】:Waiting for canvas.toDataURL() to complete before submitting blob to server在将 blob 提交到服务器之前等待 canvas.toDataURL() 完成
【发布时间】:2018-09-29 19:40:02
【问题描述】:

我在这里有一个项目要求,使用文件输入来接受文件并将其显示在画布上,同时将其作为 blob 处理并将其发送到后端进行处理。根据文件类型,可以使用不同的进程。

如果文件类型是pdf,则使用pdf.js进行处理,将pdf图像显示在画布上,同时将文件转换为blob发送到后端进行处理。到目前为止,这仅适用于单页 pdf,因为我可以直接将画布数据放入 blob 并在 toDataURL 完成后直接发送。

但是,对于多页 pdf,我无法在每个页面上运行多个 toDataURL。我的想法是,当我使用 pdf.js 的 getPage 迭代每个页面时,我将在画布上显示页面,并将画布图像作为 blob 并将其推送到数组中。处理完所有页面并将所有 blob 推入数组后,我会将其发送到后端进行处理。

var __TOTAL_PAGES, __ISMULTIPLEPAGE, __CANVAS = undefined;
var __MULTIPAGEHOLDER = [];

function showPDF(pdf_url) {
    PDFJS.getDocument({url: pdf_url}).then(function (pdf_doc) {
        __TOTAL_PAGES = pdf_doc.numPages;
        __ISMULTIPLEPAGE = __TOTAL_PAGES > 1 ? true : false;

        // Show the first page
        for (var i = 0; i < __TOTAL_PAGES; i++){
            $('#parentId').append('<canvas id="canvas-'+(i+1)+'"></canvas>');

            showPage(i+1);
    }

    }).catch(function (error) {
    /* Insert any error handling here */
    });
}

function showPage(page_no) {
    __PDF_DOC.getPage(page_no).then(function (page) {
        /* Some setup here */

        var renderContext = {
            canvasContext: /* Some value */,
            viewport: /* Some value */
        };

        // Render the page contents in the canvas
        page.render(renderContext).then(function () {

            __CANVAS = document.getElementById('canvas-'+page_no);

            // $('#go_pdf').click();
            if (__ISMULTIPLEPAGE){
                var thisPageURL = __CANVAS.toDataURL();
                    thisPage = dataURLtoBlob(thisPageURL);
                    __MULTIPAGEHOLDER.push(thisPage);

                if (__MULTIPAGEHOLDER.length === __TOTAL_PAGES){
                    // Once all blob are ready then only will submit to backend
                    submitPDFtoBackend(__MULTIPAGEHOLDER);
                }
            } else {
                var pdfData = [];
                if (pdfCanvas != null) {
                    var data = __CANVAS.toDataURL();
                    pdfData.push(dataURLtoBlob(data));
                }

                submitPDFtoBackend(pdfData);
            }
        });
    });
}

但上面的操作并没有达到我的预期,因为有时即使 toDataURL 仍在运行,submitPDFtoBackend 方法仍然会被调用。我只希望仅在完成所有 toDataURL 并且所有 blob 都已推送到数组后才调用 submitPDFtoBackend。

我读过有关将 toDataURL 进程作为承诺的信息,因此可以使用 $.when 对承诺执行提交方法,但我不确定这是否可行。像

$.when.apply(null, promise).then(function() {
    submitPDFtoBackend(__MULTIPAGEHOLDER);
});

但我不确定如何做到这一点。

谢谢

【问题讨论】:

    标签: javascript jquery pdf.js


    【解决方案1】:
    1. 您可以通过 canvas.toBlob 直接转到 blob,而不是先转到 dateURL,然后再从那里转到 blob
    2. 要检查 blob 是否准备就绪,您可以将其捕获在 img 元素的 onload 处理程序中,然后在 onload 处理程序中调用 submitPDFToBackend。下面sn-p直接来自mdn

    var canvas = document.getElementById('canvas');

    canvas.toBlob(function(blob) {
    var newImg = document.createElement('img'),
    url = URL.createObjectURL(blob);
    newImg.onload = function() {
    // no longer need to read the blob so it's revoked
    URL.revokeObjectURL(url);
    };
    newImg.src = url;
    document.body.appendChild(newImg);
    

    });

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-24
      • 1970-01-01
      • 2015-04-24
      相关资源
      最近更新 更多