【问题标题】:xmlhttprequest for pdf file works for sync but not asyncpdf文件的xmlhttprequest适用于同步但不是异步
【发布时间】:2016-07-12 18:05:48
【问题描述】:

我正在测试一些代码,通过捕获用户点击的链接从 chrome 扩展中抓取 PDF。同步 xm​​lhttprequest 适用于指向 html 文档和 pdf 的链接。但是,异步似乎永远不会返回。我是不是做错了什么?

这是我的 content.js 在失败的异步版本中的最小演示示例:

var links = document.getElementsByTagName("a");

function getlink(link) {
    console.log("looking for link");
    var x = new XMLHttpRequest();
    x.open("GET", link, true);
    x.onload = function(e) {
        console.log("loaded");
        console.log(link);
        console.log(x.status);
    };

    x.onerror = function (e) {
        console.error(x.statusText);
    };

    x.send(null);
}

for (i = 0, len = links.length; i < len; i++) {
    var l = links[i]
    l.addEventListener("click", function() {
        console.log(this.href);
        getlink(this.href);
    }, false);
};

使用该代码,当单击指向 html 文档的链接时,它会按预期记录“寻找链接”、“已加载”、url 和“200”。这也是当我重写此代码以仅同步获取时它记录的内容(通过将open 方法的最后一个参数切换为true,并将所有日志记录代码从unload 移到调用函数。

但是当我异步获取 pdf 时,它只是说“正在寻找链接”然后静音---没有错误,没有响应。它确实给了我一个信息:

资源解释为文档,但使用 MIME 类型 application/pdf 传输:“[URL TO PDF]”。

但我不确定这是来自 javascript 链接捕获,还是普通的浏览器点击操作。

有人对此有任何见解吗?不幸的是,我认为我必须异步执行此操作...

【问题讨论】:

    标签: javascript ajax http asynchronous google-chrome-extension


    【解决方案1】:

    在同步模式下,在默认链接事件处理程序看到点击事件之前获取 PDF。

    在异步模式下,浏览器首先处理单击事件并在当前选项卡中加载 PDF 文件,因此原始页面及其所有事件处理程序和回调都会被销毁。

    方法一:使用background (event) page脚本:

    • 在后台页面中定义一个消息监听器:chrome.runtime.onMessage,它将异步获取 PDF
    • 在点击处理程序中使用chrome.runtime.postMessage发送带有PDF url的消息

    方法二:禁用默认点击行为:

        l.addEventListener("click", function(e) {
            e.preventDefault();
            //e.stopPropagation(); // may be needed if the page has a custom event handler
            //e.stopImmediatePropagation(); // same reason
            console.log(this.href);
            getlink(this.href);
        }, false);
        .........
    

    也许在获取 PDF 后进行导航:

    function getlink(link) {
        .........
        x.onload = function(e) {
            console.log("loaded");
            console.log(link);
            console.log(x.status);
            window.location.href = link;
        };
        .........
    

    【讨论】:

    • 谢谢!我会试试的。与此同时,出于好奇,为什么加载新的 HTML 页面不会异步破坏上下文?
    • 它总是这样,除非new HTML page 是指通过 AJAX 和/或 history state manipulation 动态加载的页面。
    • 嗯,但是当我单击链接以加载新的 html 页面时,异步功能按预期工作,仅在 pdf 上失败...
    • 可能是因为在 XMLHttpRequest 中加载 PDF 需要更多时间,而在浏览器破坏原始页面的窗口和文档对象之前获取 HTML 页面(很小)。
    • 好吧,不管那个特定的 html/pdf 分歧之谜的原因是什么,你的修复(方法 2 --- 我的代码需要从原始页面执行)就像一个魅力,所以谢谢你!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-27
    • 2015-10-28
    • 1970-01-01
    • 2018-06-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多