Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[bug] Can not download in front end #4633

Open
zhaoygcq opened this issue Jul 9, 2022 · 18 comments
Open

[bug] Can not download in front end #4633

zhaoygcq opened this issue Jul 9, 2022 · 18 comments
Labels
scope: core Core packages of Tauri status: backlog Issue is ready and we can work on it type: bug

Comments

@zhaoygcq
Copy link

zhaoygcq commented Jul 9, 2022

Describe the bug

in the browser, we can use like this:

 const eleLink = document.createElement("a");
                eleLink.href = url;
                eleLink.download = `${title} - ${artist}`;
                eleLink.style.display = "none";
                document.body.appendChild(eleLink);
                eleLink.click();
                document.body.removeChild(eleLink);

to download file in front; but in tauri,this function can not take effect.

Reproduction

No response

Expected behavior

No response

Platform and versions

› OS: Mac OS 12.4.0 X64
  › Node.js: 16.14.0
  › npm: 8.3.1
  › pnpm: 6.32.3
  › yarn: 1.22.17
  › rustup: 1.24.3
  › rustc: 1.61.0
  › cargo: 1.61.0
  › Rust toolchain: stable-aarch64-apple-darwin

Stack trace

No response

Additional context

No response

@zhaoygcq zhaoygcq added status: needs triage This issue needs to triage, applied to new issues type: bug labels Jul 9, 2022
@amrbashir amrbashir added the status: upstream This issue is blocked by upstream dependencies and we need to wait or contribute upstream fixes label Jul 9, 2022
@amrbashir
Copy link
Member

upstream: tauri-apps/wry#349

@zhaoygcq
Copy link
Author

it seems there is no answer; @amrbashir

@FabianLars
Copy link
Member

it seems there is no answer;

It's a tracking issue = it's not implemented yet.

@zhaoygcq
Copy link
Author

it seems there is no answer;

It's a tracking issue = it's not implemented yet.

i see, thanks

@FabianLars FabianLars added scope: core Core packages of Tauri status: backlog Issue is ready and we can work on it and removed status: upstream This issue is blocked by upstream dependencies and we need to wait or contribute upstream fixes status: needs triage This issue needs to triage, applied to new issues labels Oct 19, 2022
@FabianLars FabianLars moved this to 📋 Backlog in Roadmap Oct 19, 2022
@candrewlee14
Copy link

It looks like this has been solved upstream.
Has that made it into any releases for tauri?
Are there any workarounds?

@matthme
Copy link
Contributor

matthme commented Jan 30, 2023

Yes, still not working on macOS with tauri 1.2.4. It does work on Linux though at least since tauri 1.2.3. So has it maybe only been partially fixed by tauri-apps/wry#530?

@FabianLars
Copy link
Member

FabianLars commented Jan 30, 2023

it still needs to be implemented in Tauri. wry#530 just made it possible to do so (by adding new apis). 530 by itself shouldn't have added any behavior changes outside these new apis.

@reupen
Copy link
Contributor

reupen commented Jun 8, 2023

My experience of the out of the box behaviour of downloads (Tauri 1.3.0):

  • On Windows, files are downloaded to the downloads folder. The web view shows a notification. If the file already exists, the new file is saved with a unique name.
  • On Linux (Ubuntu 22.04), files are downloaded to the downloads folder. There is no notification from the web view. If the file already exists, it's deleted and no new file is saved.

(I don't have access to macOS to test there.)

@ManuelRauber
Copy link

My experience of the out of the box behaviour of downloads (Tauri 1.3.0):

  • On Windows, files are downloaded to the downloads folder. The web view shows a notification. If the file already exists, the new file is saved with a unique name.
  • On Linux (Ubuntu 22.04), files are downloaded to the downloads folder. There is no notification from the web view. If the file already exists, it's deleted and no new file is saved.

(I don't have access to macOS to test there.)

On macOS nothing seems to happen at all. No errors in the console, no file is downloaded.

At least not to this locations:

  • Desktop
  • Documents
  • User Folder ~/

@matthme
Copy link
Contributor

matthme commented Sep 20, 2023

Is there any plan for this being added to tauri still? It's still not working in tauri 1.4 almost one year after it being fixed upstream (it was planned apparently to be added to tauri 1.3). It's quite a critical issue for us.

@github-project-automation github-project-automation bot moved this to 📬Proposal in Roadmap Sep 26, 2023
@rosseyre
Copy link

Also critical for us if there is a chance of bringing this closer on the roadmap

@kirill-konshin
Copy link

Temporary solution:

import { saveAs } from 'file-saver';
import { save } from '@tauri-apps/api/dialog';
import { writeTextFile } from '@tauri-apps/api/fs';

export const downloadFile = async (filename, text, type = 'application/json') => {
    if (window.__TAURI__) {
        const filePath = await save({ defaultPath: filename });
        await writeTextFile(filePath, text);
    } else {
        saveAs(new Blob([text], { type }), filename);
    }
};

Don't forget to enable dialogs.

@Amerlander
Copy link

I use Tauri as a wrapper to serve static builds. I guess the temporary solution only works if I would change all links to use the downloadFile-function instead of just being links?

@ImageDeeply
Copy link

@FabianLars Would be useful to know if this issue is likely to be fixed in the 2.0 release.

@FabianLars
Copy link
Member

i don't know either, probably not in 2.0.0 because of the audit 🤔

@gusxodnjs
Copy link

Is there any way to solve this part in the latest version of tauri?
In my case, the download code is in the external domain, so I need a way to resolve it in the Tauri app if possible.

@gusxodnjs
Copy link

I was in a situation where I couldn't install the tauri module on the front-end, and I eventually handled it like this. Hope it helps someone.

  • Frontend
export const useSaveFile = () => {
  const blobToBase64 = async (blob: Blob) => {
    return new Promise((resolve, reject) => {
      const reader = new FileReader()
      reader.onloadend = () => {
        resolve((reader.result as string).split(',')[1])
      }
      reader.onerror = reject
      reader.readAsDataURL(blob)
    })
  }

  const saveFile = async (blob: Blob, fileName: string) => {
    if (window.isTauri) {
      const base64Data = await blobToBase64(blob)
      await invoke(`save_file`, { filename: fileName, data: base64Data })
    } else {
      saveAs(blob, fileName)
    }
  }

  return { saveFile }
}
  • Backend
use base64::engine::general_purpose::STANDARD;
use base64::Engine;
use std::fs::File;
use std::io::Write;

#[tauri::command]
fn save_file(app_handle: AppHandle, filename: &str, data: &str) {
  let data = data.to_owned().clone();
  app_handle
    .dialog()
    .file()
    .set_file_name(filename)
    .save_file(move |file_path| {
      match STANDARD.decode(&data) {
        Ok(decoded_data) => {
          let file_path = file_path.unwrap().into_os_string().into_string().unwrap();
          match File::create(file_path) {
            Ok(mut file) => {
              if let Err(e) = file.write_all(&decoded_data) {
                println!("Failed to write to file: {}", e);
              }
            }
            Err(e) => {
              println!("Failed to create file: {}", e);
            }
          }
        }
        Err(e) => {
          println!("Failed to decode base64: {}", e);
        }
      }
    });
}

@wesloong
Copy link

I was in a situation where I couldn't install the tauri module on the front-end, and I eventually handled it like this. Hope it helps someone.

  • Frontend
export const useSaveFile = () => {
  const blobToBase64 = async (blob: Blob) => {
    return new Promise((resolve, reject) => {
      const reader = new FileReader()
      reader.onloadend = () => {
        resolve((reader.result as string).split(',')[1])
      }
      reader.onerror = reject
      reader.readAsDataURL(blob)
    })
  }

  const saveFile = async (blob: Blob, fileName: string) => {
    if (window.isTauri) {
      const base64Data = await blobToBase64(blob)
      await invoke(`save_file`, { filename: fileName, data: base64Data })
    } else {
      saveAs(blob, fileName)
    }
  }

  return { saveFile }
}
  • Backend
use base64::engine::general_purpose::STANDARD;
use base64::Engine;
use std::fs::File;
use std::io::Write;

#[tauri::command]
fn save_file(app_handle: AppHandle, filename: &str, data: &str) {
  let data = data.to_owned().clone();
  app_handle
    .dialog()
    .file()
    .set_file_name(filename)
    .save_file(move |file_path| {
      match STANDARD.decode(&data) {
        Ok(decoded_data) => {
          let file_path = file_path.unwrap().into_os_string().into_string().unwrap();
          match File::create(file_path) {
            Ok(mut file) => {
              if let Err(e) = file.write_all(&decoded_data) {
                println!("Failed to write to file: {}", e);
              }
            }
            Err(e) => {
              println!("Failed to create file: {}", e);
            }
          }
        }
        Err(e) => {
          println!("Failed to decode base64: {}", e);
        }
      }
    });
}

that's nice

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
scope: core Core packages of Tauri status: backlog Issue is ready and we can work on it type: bug
Projects
Status: 📬Proposal
Development

No branches or pull requests