¿Cómo puedo mostrar un cuadro de diálogo Guardar como en una aplicación de Electron?

Estoy escribiendo una aplicación NodeJS Electron para ser distribuida en todas las plataformas. Tengo un botón de descarga que me gustaría abrir un cuadro de diálogo Guardar como con el archivo que se proporciona desde el servidor. ¿Alguien sabe la mejor manera de hacer esto?

Estas son las cosas que he intentado que funcionan al ejecutar la aplicación de nodo localmente, pero fallan después de haber empaquetado la aplicación con el empaquetador de electrones:

  • Estableciendo window.location.href en la ubicación del archivo
  • Configuración del src de un iframe oculto en la ubicación del archivo

Cuando se ejecuta la aplicación mac empaquetada, se desencadena el evento “did-fail-load” y evita que se muestre el cuadro de diálogo Guardar como. Al mirar las solicitudes de red, puedo ver que el archivo se recupera correctamente del servidor. Parece que no puedo entender por qué se está activando el evento “did-fail-load”.

Eche un vistazo a esta página en los documentos electrónicos https://github.com/atom/electron/blob/master/docs/api/dialog.md

Hay una sección sobre dialog.showSaveDialog

Luego, puede usar la URL del cuadro de diálogo guardar con una función similar a la que se encuentra a continuación para guardarla en esa ubicación.

session.on('will-download', function(event, item, webContents) { event.preventDefault(); require('request')(item.getUrl(), function(data) { require('fs').writeFileSync('/somewhere', data); }); }); 

Se encuentra en esta página https://github.com/atom/electron/blob/master/docs/api/session.md

En el botón HTML:

  

En tu archivo javascript:

 // Include in the render side var elerem = require('electron').remote; var dialog = elerem.dialog; var app = elerem.app; var http = require('http'); var fs = require('fs'); var path = require('path'); function myUrlSaveAs(remoteUrl){ // app.getPath("desktop") // User's Desktop folder // app.getPath("documents") // User's "My Documents" folder // app.getPath("downloads") // User's Downloads folder var toLocalPath = path.resolve(app.getPath("desktop"), path.basename(remoteUrl) var userChosenPath = dialog.showSaveDialog({ defaultPath: toLocalPath }); if(userChosenPath){ download (remoteUrl, userChosenPath, myUrlSaveAsComplete) } } function myUrlSaveAsComplete(err){ alert("done"); } function download (url, dest, cb) { var file = fs.createWriteStream(dest); var request = http.get(url, function(response) { response.pipe(file); file.on('finish', function() { file.close(cb); // close() is async, call cb after close completes. }); }).on('error', function(err) { // Handle errors fs.unlink(dest); // Delete the file async. (But we don't check the result) if (cb) cb(err.message); }); };