javascript - 如何防止在 chrome 扩展程序中接收响应 header 时下载

标签 javascript google-chrome google-chrome-extension

由于这个问题Block downloading by Content-Type via Chrome Extension对我没有用,我正在打开一个新问题。 我使用以下代码根据内容类型 header 阻止下载:

chrome.webRequest.onHeadersReceived.addListener(function(details) {
    preventDownload = false;
    details.responseHeaders.push({name:"X-Content-Options",value: "no-sniff"});  // Hack 1
    details.statusLine = "HTTP/1.1 302 Moved Temporarily"; // Hack 2
    for (var i = 0; i < details.responseHeaders.length; ++i) 
    {
       if (details.responseHeaders[i].name == 'Content-Type')
        {
            var contentType = details.responseHeaders[i].value;
            if (contentType.indexOf("application/xyz")!=-1)
            {
                preventDownload = true;
            details.responseHeaders[i].value = 'text/plain'; //Hack 3
            }
            else
            {
                return {responseHeaders: details.responseHeaders};
            }
        }

    }
    if(preventDownload)
    {
        if (details.frameId === 0) // Top frame, yay!
        { 
            var scheme = /^https/.test(details.url) ? "https" : "http";
            chrome.tabs.update(details.tabId, {
            url: scheme + "://robwu.nl/204"});
            return;   //return {cancel: true}; should be used but it displays block page
        }
        return {cancel: true};
    }
    return {responseHeaders: details.responseHeaders};
}, {urls: ["<all_urls>"],types: ["main_frame", "sub_frame"]}, ['blocking', 'responseHeaders']);

我成功阻止了下载,但出现了一个错误的 Web 阻止页面。我需要让用户停留在上一页而不重新加载以显示此错误页面或以某种方式在显示此服务页面后返回。

我在上面的代码中使用了 hack,但它不会阻止下载。

最佳答案

details 是提供给您的扩展的对象,其中包含有关请求的信息。改变它的值确实对请求没有任何影响。

Since Chrome 35.0.1911.0,您可以简单地重定向到一个回复​​状态代码 204 的页面,以防止上一个页面卸载:

chrome.webRequest.onHeadersReceived.addListener(function(details) {
    // ... your code that checks whether the request should be blocked ...
    //  (omitted for brevity)
    var scheme = /^https/.test(details.url) ? "https" : "http";
    return {redirectUrl: scheme + "://robwu.nl/204" };
}, {
    urls: ["<all_urls>"],
    types: ["main_frame", "sub_frame"]
}, ["responseHeaders", "blocking"]);

如果您使用的是较旧的 Chrome 版本(例如 34-),则可以改用以下方法:

此外,为了防止文件被下载,您需要指示 Chrome 在选项卡中呈现页面。这可以通过修改 header 来完成。

  1. Content-Type 更改为 text/plain(因为它是一种轻型格式)。
  2. 添加 X-Content-Type-Options: nosniff(以防止 MIME-sniffing )。
  3. 删除 Content-Disposition header (以防止某些类型的下载)。

使用这些 header ,Chrome 将尝试在选项卡中呈现响应。这是来自其他答案的方法的来源:通过调用 chrome.tabs.update指向以 HTTP 状态代码 204 回复的资源,导航将在不离开当前页面的情况下取消。

chrome.webRequest.onHeadersReceived.addListener(function(details) {
    // ... your code that checks whether the request should be blocked ...
    //  (omitted for brevity)

    if (details.frameId === 0) { // Top frame, yay!
        // Prevent current page from unloading:
        var scheme = /^https/.test(details.url) ? "https" : "http";
        chrome.tabs.update(details.tabId, {
            url: scheme + "://robwu.nl/204"
        });

        // Prevent file from being downloaded via the headers:
        var responseHeaders = details.responseHeaders.filter(function(header) {
            var name = header.name.toLowerCase();
            return name !== 'content-type' &&
                   name !== 'x-content-type-options' &&
                   name !== 'content-disposition';
        }).concat([{
            // Change content type to something non-downloadable
            name: 'Content-Type',
            value: 'text/plain'
        }, {
            // Disable MIME-type sniffing:
            name: 'X-Content-Type-Options',
            value: 'nosniff'
        }]);
        return {
            responseHeaders: responseHeaders
        };
    }
    // else not the top frame...
    return {cancel: true};
}, {
    urls: ["<all_urls>"],
    types: ["main_frame", "sub_frame"]
}, ["responseHeaders", "blocking"]);

注意:这是一个 hacky 方法。随意将其用于个人用途,但请不要将此类扩展程序上传到 Chrome 网上应用店。

关于javascript - 如何防止在 chrome 扩展程序中接收响应 header 时下载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22593735/

相关文章:

javascript - 单击功能时取消选中其他单选按钮

javascript - CSS3 Transitions - 如何延迟 z-index 属性的重置?

google-chrome - 在 chrome 的新标签页中打开打印预览页面

javascript - chrome.webNavigation.onCompleted 和 chrome.tabs.onUpdated.addListener 与 'complete' 有什么区别

google-chrome - 在 chrome 扩展中捕获元素图像(缩放失败)

javascript - Jquery/JS - 更新下拉列表

javascript - 当名称是数组时如何使用 Javascript 修改 HTML Select

javascript - 在 chrome 扩展程序中保留页面操作的状态

c# - 在不同端口之间共享 Cookie

javascript - 防止内容脚本因页面 iframe 而多次加载