Tyl*_*mes 6 javascript dropbox electron
我正在使用Electron(以前称为Atom-Shell)来创建现有Angular Web应用程序的桌面版本.大多数东西开箱即用,但我遇到了Dropbox Chooser的一些问题.
我的网络应用程序允许用户使用选择器从Dropbox导入文件.在Electron中,这会导致BrowserWindow为选择器创建一个新的.但是,window.opener新窗口的属性为null,这基本上使Chooser窗口无法与原始窗口进行通信.这使得它无用,因为有效地选择文件什么都不做.
我知道斯莱克的桌面应用程序使用电子和不知何故,他们已经能够克服这个问题(Dropbox的选配也内侧松弛工作).
有谁知道我是否可以/如何在Electron应用程序中使用Dropbox Chooser?
tl; dr我不能在Electron应用程序中使用Dropbox Chooser,因为它打开一个window.opener设置为null 的新BrowserWindow .
好吧,我设法让这个工作了。这window.opener设置,问题之一是您在选择器代码中没有正确的来源来确保作品window.opener.postMessage()和消息到达父窗口。但还有更多。
1.电子的BrowserWindow的
BrowserWindow仅当存在nodeIntegration\xc2\xa0webSecurity并设置为 false时, Dropbox Chooser 弹出窗口才能在 Electron 中工作。现在,这些很棘手,因为如果您从现有的 中打开子窗口BrowserWindow,则无法webSecurity再更改子窗口中的 \xc2\xa0 。您可以通过以下方式更改nodeIntegration通话window.open()nodeIntegration=no第三个参数
例如:\n
window.open(\'chooser-window.html\', \'_blank\', \'可调整大小,滚动条,nodeIntegration=no\')\n\n
不过我想出了一个更好的解决方案。从进程中打开选择器窗口main看起来更有希望,因为我可以控制这两个参数(以及许多其他参数)。此外,我可以轻松地绕过基于目标/原点的通信window.opener(更多信息请参见步骤 2)。创建BrowserWindow无节点集成使其无法与主进程通信。该require方法和其他节点的好东西不可用。但是,您可以将预加载脚本传递到此 BrowserWindow,其中节点内容可用,并且您可以重新公开ipcRenderer以便再次建立与主进程的通信。
当创建一个BrowserWindow出于 Dropbox Chooser 的目的
const dropboxProxyWindow = new BrowserWindow({\n webPreferences: {\n nodeIntegration: false,\n webSecurity: false,\n preload: path.join(__dirname, \'dropbox-proxy-preload.js\'),\n },\n})\nRun Code Online (Sandbox Code Playgroud)\n\ndropbox-proxy-preload.js并在同一目录中创建一个main.js创建一个:
// NOTE: This file preloads ipc to hidden dropbox proxy window\n// where nodeIntegration is set to false.\n\nglobal.ipcRenderer = require(\'electron\').ipcRenderer\nRun Code Online (Sandbox Code Playgroud)\n\n这样,我们将拥有一个BrowserWindow可以通过 ipc 与主进程通信的子窗口,而不是通过window.opener.postMessage(). 这BrowserWindow只是我们的电子应用程序的一个辅助窗口,只是一个代理,可以确保实际的 Dropbox Chooser 可以与我们的应用程序进行通信。
2. Dropbox 选择器按钮和选择器窗口
\n\n从 Dropbox 中,您将获得一个不错的按钮,您可以将其粘贴到 JS/HTML 中,并且一切都可以开箱即用(在浏览器中)。单击该按钮后,将打开一个新窗口,您选择文件,它们将在 JS 中到达您的回调。它看起来像这样:
\n\n// in HTML\n<script type="text/javascript" src="https://www.dropbox.com/static/api/2/dropins.js" id="dropboxjs" data-app-key="YOUR-APP-KEY"></script>\n\n// in JS via button\nvar button = Dropbox.createChooseButton(options);\ndocument.getElementById("container").appendChild(button);\n\n// or in JS directly\nDropbox.choose(options);\nRun Code Online (Sandbox Code Playgroud)\n\n该dropins.js脚本确保与选择器窗口的通信正常工作。Dropbox 通过调用window.opener.postMessage()与您的窗口进行通信,第二个参数targetOrigin由脚本自动预填充dropins.js。此原始 URL 必须与您在 Dropbox 开发人员应用程序管理中定义的任何内容相匹配。
为了将其移植到 Electron,我们需要“破解”传递到 Chooser 窗口的源,因为window.locationElectron 的 HTML 文件不是您可以在 Dropbox 管理中设置的 URL。我们将通过在隐藏的浏览器窗口中打开远程 HTML 文件来完成此操作,该浏览器窗口将打开选择器。我们将隐藏的 BrowserWindow 称为代理窗口。远程 HTML 将位于我们将添加到 Dropbox 管理的域中,并且它将能够与 Chooser 进行通信。它将使用一个preload脚本启动,该脚本将确保与电子主进程的通信。从那里我们可以将数据发送到我们的应用程序。加载隐藏的代理窗口后,我们将自动单击该按钮,以便打开选择器。
3. 重写dropins.js
\n\n但还有一个问题。如果我们隐藏代理窗口,BrowserWindow从那里打开的所有内容也将被隐藏。所以我们需要重写这个选项。我们将在 dropins.js 的window.open()调用中的第三个参数中执行此操作。我们将添加show=1. 由于dropins.js默认情况下是缩小的,所以我使用 Chrome DevTools 来美化代码,然后进行所需的更改。这是要点。
最终代码
\n\n在/main.js
const dropboxProxyWindow = new BrowserWindow({\n webPreferences: {\n nodeIntegration: false,\n webSecurity: false,\n preload: path.join(__dirname, \'dropbox-proxy-preload.js\'),\n },\n show: false,\n})\n\nconst DROPBOX_CHOOSER_LINK = \'https://cdn.yourapp.com/static/dropbox-chooser.html\'\ndropboxProxyWindow.loadURL(DROPBOX_CHOOSER_LINK)\n\n// NOTE: Catch data from proxy window and send to main.\nipc.on(\'dropbox-chooser-data\', (event, data) => {\n mainWindow.webContents.send(\'dropbox-chooser-data\', data)\n})\n\nipc.on(\'dropbox-chooser-cancel\', () => {\n mainWindow.webContents.send(\'dropbox-chooser-cancel\')\n})\nRun Code Online (Sandbox Code Playgroud)\n\n在/dropbox-proxy-preload.js:
global.ipcRenderer = require(\'electron\').ipcRenderer\nRun Code Online (Sandbox Code Playgroud)\n\n远程输入https://cdn.yourapp.com/static/dropins.js:要点
远程在https://cdn.yourapp.com/static/dropbox-chooser.html:
<html>\n <head>\n <title>Dropbox Chooser</title>\n <script type="text/javascript" src="dropins.js" id="dropboxjs" data-app-key="xxx"></script>\n </head>\n <body>\n <div id="container"></div>\n <script type="text/javascript">\n var options = {\n success: function(files) {\n console.debug(\'Files from dropbox:\', files)\n if (!window.ipcRenderer || typeof window.ipcRenderer.send !== \'function\') {\n console.warn(\'Unable to send Dropbox data to App.\')\n return\n }\n window.ipcRenderer.send(\'dropbox-chooser-data\', JSON.stringify(files))\n },\n\n cancel: function() {\n if (!window.ipcRenderer || typeof window.ipcRenderer.send !== \'function\') {\n console.warn(\'Unable to send Dropbox data to App.\')\n return\n }\n window.ipcRenderer.send(\'dropbox-chooser-cancel\')\n },\n\n linkType: "preview",\n multiselect: true,\n folderselect: false,\n };\n\n var button = Dropbox.createChooseButton(options);\n document.getElementById("container").appendChild(button);\n button.click() // automatically open click on the button so the Chooser opens\n </script>\n </body>\n</html>\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
595 次 |
| 最近记录: |