簡體   English   中英

從 SFTP 下載時如何向用戶顯示反饋?

[英]How can I show feedbacks to users while downloading from SFTP?

我有

單擊下載按鈕時,下載文件大約需要 15 秒,因為它必須 SFTP 到服務器,找到正確的路徑/文件,並返回響應下載

在此處輸入圖像描述

HTML

<a class="btn btn-primary btn-sm text-primary btn-download-1" onclick="startDownload('1')"><i class="fa fa-download "></i></a>

注意:其中 1 是我知道它是哪個文件的關鍵...


馬上

該按鈕將觸發下面的這個function

function startDownload(interfaceId) {
    window.location = "/nodes/interface/capture/download?port=" + interfaceId;
    console.log(interfaceId);
}

它基本上刷新頁面並調用該下載路線

/節點/接口/捕獲/下載

public function download_files()
{

    $dir = '';
    $portNumber = Request::get('port');
    $zipMe = false;

    $remotePath = "/home/john/logs/".$dir."/";

    if (!isset($dir) || $dir == null) {
        return redirect()->back()->withInput()->withFlashDanger('SFTP Could not connect.');
    }

    $acsIp =  explode('://', env('ACS_URL'));
    $acsIp =  explode(':',$acsIp[1])[0];
    $sftp = new SFTP($acsIp.':22');

    if (!$sftp->login('john', '***')) {
        return redirect()->back()->withInput()->withFlashDanger('SFTP Could not connect.');
    }


    // Get into the Specified Directory
    $sftpConn = Storage::disk('sftp');

    $SFTPFiles = $sftpConn->allFiles('/'.$dir);

    if ( count($SFTPFiles) > 0 ) {
        foreach ($SFTPFiles as $file) {
            $fileName = $file;
            break;
        }

    } else {
        \Log::info('Files Not found in the Remote!');
        return redirect()->back()->withInput()->withFlashDanger('Files Not found in the Remote!');
    }

    // Create and give 777 permission to remote-files directory
    if (!is_dir(public_path('remote-files/'.$dir))) {
        mkdir(public_path('remote-files/'.$dir), 0777, true);
    }

    $filesToZip = [];

    foreach ( $SFTPFiles as $fileName ) {
        if ( $fileName == '..' || $fileName == '.' ) {
            continue;
        } else if ( $fileName == '' ) {
            \Log::info('File not found');
            continue;
        }

        $fileName     = explode("/", $fileName);
        $onlyFileName = (!empty($fileName) && isset($fileName[1])) ? $fileName[1] : "";
        $filepath = $remotePath.$onlyFileName;

        if (strpos($onlyFileName , $portNumber) !== false) {


            // Download the remote file at specified location in Local
            if (!$sftp->get($filepath, 'remote-files/'.$dir.'/'.$onlyFileName))
            {
                die("Error downloading file ".$filepath);
            }

            $file = public_path('remote-files/'.$dir.'/').$onlyFileName;

            $headers = array(
                'Content-Description: File Transfer',
                'Content-Type: application/octet-stream',
                'Content-Disposition: attachment; filename="'.basename($file).'"',
                'Cache-Control: must-revalidate',
                'Pragma: public',
                'Content-Length: ' . filesize($file)
            );

            return Response::download($file, $onlyFileName, $headers);

        }

        // IF File is exists in Directory
        if ( file_exists( public_path('remote-files/'.$dir.'/').$onlyFileName ) ) {

            $filesToZip[] = public_path('remote-files/'.$dir.'/').$onlyFileName;
            \Log::info('File Generated '.'remote-files/'.$dir.'/'.$onlyFileName);


            // Remove Files from public/remote-files
            $this->removeDirAndFiles('', public_path('remote-files/'.$dir));
            exit;


        } else {
            \Log::info('File not Generated '.'remote-files/'.$dir.'/'.$onlyFileName);
        }
    }
}

結果

它正在工作,但不知何故,它會在那里停留 15 秒而沒有任何反饋。 這真的很糟糕,用戶不知道發生了什么。

我想顯示一個模式說“正在下載,請不要關閉窗口” ,但我不知道該怎么做,因為我必須使用 GET 來下載文件。我是現在有點卡住了。

對我有什么建議嗎?

由於延遲是在服務器端,我相信你可以做兩種方式:

  1. 有一條路線來創建隊列作業並確定進度,還有一條路線供用戶在服務器中下載下載的文件。 用戶將每秒 ping 到第一條路由以確定狀態。

    這個想法是在每次創建 session 時生成一個唯一 ID,將其存儲在一個由download_files()路由和另一個路由共享的數組中,以啟動download_files()並存儲其結果。

    例子:

     $global_progress = array(); $global_files = array(); public function checkup_progress($id = null) { if ($id == null) { // this is new request, create job here $id = generate_id_func(); download_file_job($id); } else if ($global_progress[$id],= "FINISHED") { // return $global_progress[$id] result } else { // finished; return download link // return route to "link_to_download_file/$id" } } public function download_file_job($id) { $global_progress[$id] = "NEW"; // some code $global_progress[$id] = "IN PROGRESS (1)"; // more code // more state here $global_files[$id] = $file; $global_progress[$id] = "FINISHED": } public function link_to_download_file($id) { // code here return Response:,download($file, $onlyFileName; $headers); }
  2. 如果您不想更改任何內容,您可以使用 websocket 更新下載 state,然后將文件發送到客戶端。 But this would be restricted by the filesize as websocket are handled in javascript, which means download must be stored javascript object in browser memory first.

在進行重定向之前,顯示一個包含您選擇的消息的覆蓋 div 這不需要在服務器端做任何事情。

function startDownload(interfaceId) {
    document.getElementById("overlay").style.display = "block"; // Show the overlay
    window.location = "/nodes/interface/capture/download?port=" + interfaceId;
    console.log(interfaceId);
}

CSS

#overlay {
  position: fixed; /* Sit on top of the page content */
  display: none; /* Hidden by default */
  width: 100%; /* Full width (cover the whole page) */
  height: 100%; /* Full height (cover the whole page) */
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0,0,0,0.5); /* Black background with opacity */
  z-index: 2; /* Specify a stack order in case you're using a different order for other elements */
  cursor: pointer; /* Add a pointer on hover */
  display: flex;
  justify-content: center;
  align-items: center;
  color: yellow;
}

HTML

<div id="overlay">
  Downloading is in progress, please don't close the window
</div> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM