【问题标题】:How do I download a file in a brackets-shell app?如何在括号外壳应用程序中下载文件?
【发布时间】:2013-11-08 10:18:25
【问题描述】:

我正在使用 Brackets-shell 为 Windows 和 OSX 构建桌面打包应用程序。在 Brackets shell 上运行的应用程序能够从服务器打开动态生成的 Excel 工作表和 PDF 文件。在普通浏览器中,对文件的请求是在允许用户保存文件的隐藏 iFrame 中完成的。但是,在 Brackets shell 中,不会加载文档。相反,它会在 iFrame 中返回以下错误

Failed to load URL http://my.server.com/generate/test.pdf with error (-3)

谁能告诉我如何让 Brackets 下载并将文件保存在本地 FS 上?我已经尝试过brackets.app.openURLInDefaultBrowser 但这不起作用,因为默认窗口没有应用程序使用的身份验证cookie。

谢谢

【问题讨论】:

  • 你找到解决办法了吗?

标签: html iframe browser adobe-brackets brackets-shell


【解决方案1】:

我认为括号壳(还)不支持这 - 似乎基于CEF 的应用程序必须专门实现括号壳尚未完成的“下载处理程序”。 This AppJS bug comment 说的差不多(因为那个 shell 也是基于 CEF 的)。那里使用 Node 进行下载的建议也适用于括号外壳,但您会遇到与 openURLInDefaultBrowser() 相同的问题。

如果您要下载纯文本内容,则可以完全使用括号壳的 appshell.fs 文件 IO API 来完成,这将修复 cookie 的情况。但这些 API 目前只处理 UTF-8 文本。

所以我认为你需要修补括号外壳来实现下载功能。起点是实现CefDownloadHandler 并从CefClient::GetDownloadHandler 返回。看起来 CEF 会为您处理“另存为”对话框 (see show_dialog arg of callback),因此您可能根本不需要编写太多代码。

【讨论】:

    【解决方案2】:

    这可以使用 Node 查看:https://github.com/adobe/brackets/wiki/Brackets-Node-Process:-Overview-for-Developers#Architecture

    从标题开始:第 0 步:设置扩展。

    总而言之,您可以在 websocket 上与括号中的节点进行通信。有了这个,您可以动态加载节点模块并执行它们。

    现在,如果您不使用 require,这些说明可能会非常繁重。如果是,请在此处停止并使用这些说明。如果您不使用 require 您可以“取消”要求代码并删除您需要的内容。我正在进行的一个项目必须这样做,因为我们意识到括号不支持 pdf 下载的时间太晚了。

    因此,以下是一些说明,可以将您需要的内容破解到您的应用程序中。同样,这是对一些非常好的代码的解构。

    警告:这不漂亮,也不是让这个工作的括号方法。

    WARNING 警告认真

    创建你的节点保存模块

    这与上述说明中的操作相同,并且仍将使用 require,但它已加载到节点中,因此您不必担心项目的应用程序部分的 require。保存代码类似这样:https://github.com/joelrbrandt/brackets-simple-node/blob/master/node/SimpleDomain.js

    (function () {
        "use strict";
        var url = require('url');
        var http = require('http');
        var https = require('https');
        var fs = require('fs');
    
        function cmdSaveFileFromUrl(urlString, dest) {
            var requestUrlObject = url.parse(urlString, true);
            var options = {
                hostname: requestUrlObject.hostname,
                port: +requestUrlObject.port,
                path: requestUrlObject.path
            };
            var requester = requestUrlObject.protocol === "http:" ? http : https;
            var file = fs.createWriteStream(dest);
            var request = requester.get(options, function(response) {
                response.on('end', function(){
                    file.on('finish', function() {
                        file.close();
                    });
                });
                response.pipe(file);
            });
        }
    
        function init(DomainManager) {
          ...
        }
        exports.init = init;
    }());
    

    动态加载此模块

    现在您需要获取将动态加载此模块的 appshell 代码。为此,您基本上需要括号中的整个 NodeConnection 模块。该模块负责使 websocket 到节点工作。因此,如果您没有像我一样的要求,您可以“取消”要求它。撕掉导出的东西,让它自己返回,把它包含在你的 index.html 中。

    function NodeConnection() {
        "use strict";
    ....
        return NodeConnection;
    }
    

    调用节点连接的代码

    最后你需要使用节点连接来加载模块并发送命令来执行它的任务,括号壳(appshell)再次为此提供模块,但如果你没有需要你需要拉出什么你需要。实用方法中的大多数方法都可以很容易地取出。 https://github.com/joelrbrandt/brackets-simple-node/blob/master/main.js

    从任何地方:

    function chain() {
        var functions = Array.prototype.slice.call(arguments, 0);
        if (functions.length > 0) {
            var firstFunction = functions.shift();
            var firstPromise = firstFunction.call();
            firstPromise.done(function () {
                chain.apply(null, functions);
            });
        }
    }
    function connect() {
        var connectionPromise = nodeConnection.connect(true);
        connectionPromise.fail(function () {
            console.error("[brackets-node] failed to connect to node");
        });
        return connectionPromise;
    }
    function getNativeBracketsDirectoryPath() {
        var pathname = decodeURI(window.location.pathname);
        var directory = pathname.substr(0, pathname.lastIndexOf("/"));
        return convertToNativePath(directory);
    }
    function convertToNativePath(path) {
        path = unescape(path);
        if (path.indexOf(":") !== -1 && path[0] === "/") {
            return path.substr(1);
        }
    
        return path;
    }
    function loadDomain() {
       var root_url = getNativeBracketsDirectoryPath();
       var path = root_url + "/node/YOUR_NODE_MODULE_FROM_STEP_ONE.js";
       var loadPromise = nodeConnection.loadDomains([path], true);
       loadPromise.fail(function () {
           console.log("[brackets-node] failed to load domain");
       });
       return loadPromise;
    }
    function saveFile(inUrl, path) {
        path = path || window.appshell.app.getUserDocumentsDirectory()+"/file";
        var memoryPromise = nodeConnection.domains.yourdomain.saveFileFromUrl(inUrl, path);
        memoryPromise.fail(function (err) {
            console.error("[brackets-node] failed to run saveFileFromUrl", err);
        });
        memoryPromise.done(function () {
                        console.log("Check the file");
        });
        return memoryPromise;
    }
    var  NodeConnectionObject = NodeConnection();
    var nodeConnection = new NodeConnectionObject();
    chain(connect, loadDomain, function(){
       return saveFile(urlToFetch, file)
    });
    

    我希望这对某人有所帮助。

    【讨论】:

      猜你喜欢
      • 2014-06-12
      • 2012-08-28
      • 1970-01-01
      • 2015-06-29
      • 1970-01-01
      • 1970-01-01
      • 2018-01-25
      • 1970-01-01
      • 2017-03-18
      相关资源
      最近更新 更多