我正在使用Brackets-shell为Windows和OSX构建桌面打包的应用程序。在Brackets shell上运行的应用程序能够从服务器打开动态生成的Excel工作表和PDF文件。在普通浏览器中,对文件的请求是在隐藏的iFrame中完成的,该iFrame允许用户保存文件。但是在Brackets shell中,未加载文档。相反,它会在iFrame中返回以下错误
Failed to load URL http://my.server.com/generate/test.pdf with error (-3)
有谁能告诉我如何让Brackets下载并将文件保存在本地FS上?我已经尝试过bracket.app.openURLInDefaultBrowser,但由于默认窗口没有应用程序使用的身份验证cookie,因此无效。
由于
答案 0 :(得分:2)
我认为这还没有(括号)shell支持 - 似乎基于CEF的应用程序必须专门实现一个“下载处理程序”,其中括号shell尚未完成。 This AppJS bug comment说的大致相同(因为shell也是基于CEF的)。那里使用Node进行下载的建议也可以使用bracket-shell,但是你会遇到与使用openURLInDefaultBrowser()
时相同的auth cookie问题。
如果您正在下载纯文本内容,可以使用bracket-shell的appshell.fs
文件IO API完全完成,这将修复cookie的情况。但这些API目前只处理UTF-8文本。
所以我认为你需要修补bracket-shell来实现下载功能。起点是实施CefDownloadHandler
并从CefClient::GetDownloadHandler
返回。看起来CEF会为您处理“另存为”对话框(see show_dialog
arg of callback),因此您可能根本不需要编写太多代码。
答案 1 :(得分:1)
这可以使用Node查看:https://github.com/adobe/brackets/wiki/Brackets-Node-Process:-Overview-for-Developers#Architecture
来完成从标题开始:步骤0:设置扩展名。
总之,您可以在websocket上的括号中与节点进行通信。通过这种方式,您可以动态加载节点模块并执行它们。
如果您不使用require,这些说明可能非常繁重。如果是,请停止并使用这些说明。如果您没有使用require,您可以“取消”代码并删除您需要的内容。我所参与的项目必须这样做,因为我们实现括号不支持pdf下载的时间有多晚。
以下是一些说明,它们会破解您的应用程序所需的内容。这又是对一些非常好的代码的解构。
警告:这不是很漂亮,也不是让这种方式有效的括号方式。
警告警告严重
创建节点保存模块
这与上面的说明完全相同,但仍然会使用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;
}
调用节点连接的代码
最后你需要使用节点连接来加载模块并发送命令来执行它的任务,再次使用bracket-shell(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)
});
我希望这有助于某人。