Javascript για την εκτέλεση επεξεργασίας μετά τη λήψη ενός αρχείου

Σελίδα ενημέρωση :
Ημερομηνία δημιουργίας σελίδας :

Περιβάλλον επαλήθευσης λειτουργίας

Οπτικό στούντιο
  • Visual Studio 2022
ASP.NET Πυρήνας
  • 8.0 (σελίδες Razpr, MVC)
Προγράμματα περιήγησης ιστού
  • Άκρη 119

Περιβάλλον λειτουργίας

Visual Studio (εάν συμπεριλάβετε επίσης προγράμματα διακομιστή)
  • Visual Studio 2022
ASP.NET Core (εάν περιλαμβάνει επίσης προγράμματα διακομιστή)
  • 8.0 (σελίδες Razpr, MVC)
Προγράμματα περιήγησης ιστού
  • Άκρο
  • Google Chrome
  • Άλλα προγράμματα περιήγησης (δεν ελέγχονται όλα)

(* Το κύριο σώμα αυτής της συμβουλής είναι η διαδικασία από την πλευρά του πελάτη, οπότε η πλευρά του διακομιστή μπορεί να είναι οτιδήποτε)

Αρχικά

Ο κύριος στόχος αυτών των συμβουλών είναι το πρόγραμμα-πελάτης (Javascript) και το πρόγραμμα διακομιστή υπάρχει μόνο για λήψη αρχείων. Επομένως, δεν έχει σημασία ποιο είναι το πρόγραμμα διακομιστή, αρκεί να σας κάνει να κάνετε λήψη του αρχείου.

Ζητήστε από τους χρήστες να κατεβάζουν αρχεία κατά την πρόσβαση σε αυτά από το διακομιστή

Ο κ. / κα σας επιτρέπει να κατεβάζετε αρχεία όταν λαμβάνετε ένα αίτημα. Εκείνη τη στιγμή, περιμένουμε σκόπιμα ένα ορισμένο χρονικό διάστημα στο διακομιστή, ώστε να είναι εύκολο να κατανοήσουμε την έναρξη και το τέλος της λήψης.

Δείτε τι συμβαίνει στην πλευρά του διακομιστή των Razor Pages και MVC: Μπορείτε να το εφαρμόσετε σε άλλα έργα, όπως το Web API.

Σελίδες ξυραφιών : Σελίδες/Index.cshtml.cs

// 省略

namespace DownloadCompleteNotifyRazorPages.Pages
{
  public class IndexModel : PageModel
  {
    // 省略

    /// <summary>時間をかけてファイルをダウンロードします。</summary>
    public async Task<IActionResult> OnGetDownload()
    {
      // ダウンロード開始と完了を明確にする目的で待機を入れる
      await Task.Delay(5000);

      // 適当にファイルを作って返す
      var fileSize = 10_000_000;
      var sb = new System.Text.StringBuilder(fileSize);
      for (int i = 0; i < fileSize; i++) sb.Append('a');
      using var stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(sb.ToString()));
      return File(stream.ToArray(), "text/plain", $"ダウンロード.txt");
    }
  }
}

MVC : Coletollers/HomeController.cs

// 省略

namespace DownloadCompleteNotifyMvc.Controllers
{
  public class HomeController : Controller
  {
    // 省略

    /// <summary>時間をかけてファイルをダウンロードします。</summary>
    public async Task<IActionResult> Download()
    {
      // ダウンロード開始と完了を明確にする目的で待機を入れる
      await Task.Delay(5000);

      // 適当にファイルを作って返す
      var fileSize = 10_000_000;
      var sb = new System.Text.StringBuilder(fileSize);
      for (int i = 0; i < fileSize; i++) sb.Append('a');
      using var stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(sb.ToString()));
      return File(stream.ToArray(), "text/plain", $"ダウンロード.txt");
    }
  }
}

Επεξεργασία πελατών

Κανονικά, κάνετε λήψη ενός αρχείου μεταβαίνοντας σε μια καθορισμένη διεύθυνση URL σε ένα πρόγραμμα περιήγησης ιστού. Εάν θέλετε να κάνετε κάτι μετά την ολοκλήρωση της λήψης, μπορείτε να εκτελέσετε τη λήψη με Javascript.

Υπάρχουν πολλοί τρόποι για να γίνει αυτό, αλλά σε αυτή την περίπτωση, θα χρησιμοποιήσουμε , η οποία είναι επίσης XMLHttpRequest η προέλευση της ασύγχρονης επεξεργασίας. Μπορείτε επίσης να χρησιμοποιήσετε τις συναρτήσεις ajax jQuery ή το API Fetch.

ahref Η διεύθυνση URL λήψης είναι γραμμένη στην ετικέτα και id η διαδικασία εκτελείται όταν κάνετε κλικ σε αυτήν που έχει οριστεί σεdownload.

$('#download').click(function (e) {
  console.log('ダウンロードを開始します。');
  e.preventDefault();  // href による画面遷移を抑止
  let url = $(e.target).attr('href');  // href からダウンロード URL 取得

  const xhr = new XMLHttpRequest();
  xhr.open('GET', url, true);   // ダウンロード先 URL 設定
  xhr.responseType = 'blob';   // バイナリデータ取得であることを指示

  // ダウンロード完了後の処理を設定。この時点ではデータは取得してクライアントにありますが保存はしていません。
  xhr.onload = function (oEvent) {
    if (xhr.status !== 200) {
      console.log(`データの取得に失敗しました。(status=${xhr.status})`);
    } else {
      // 取得したデータ
      let blob = xhr.response;

      // レスポンスヘッダーからサーバーから送られてきたファイル名を取得する
      let fileName = '';
      let disposition = xhr.getResponseHeader('Content-Disposition');
      if (disposition && disposition.indexOf('attachment') !== -1) {
        let filenameRegex = /filename[^;=\n]=((['"]).*?\2|[^;\n]*)/;
        let matches = filenameRegex.exec(disposition);
        if (matches != null && matches[1]) {
          // 「filename*=UTF-8''%E3%83%87%E3%83%BC%E3%82%BF.txt;」からファイル名を取得
          fileName = decodeURI(matches[1].replace(/['"]/g, '').replace('utf-8', '').replace('UTF-8', ''));
        }
      }
      if (fileName === '') {
        // ファイル名を取得できなかったら念のため URL をファイル名とする
        let fileName = url.match('.+/(.+?)([\?#;].*)?$')[1];
      }

      // Blob オブジェクトを指す URL オブジェクトを作る
      let objectURL = window.URL.createObjectURL(blob);
      // リンク(<a>要素)を生成し、JavaScript からクリックする
      let link = document.createElement('a');
      document.body.appendChild(link);
      link.href = objectURL;
      link.download = fileName;   // download を指定するとブラウザで開くことなくダウンロードになる
      link.click();
      document.body.removeChild(link);

      console.log('ダウンロードを完了しました。');
    }
  };

  // リクエスト開始
  xhr.send();
});

a Κανονικά, εάν αφήσετε το στοιχείο κλικ, η προεπιλεγμένη διαδικασία λήψης θα μετακινηθεί, επομένως e.preventDefault(); καλούμε να απενεργοποιήσετε την προεπιλεγμένη διαδικασία.

href Λάβετε τη διεύθυνση URL λήψης από και XMLHttpRequest GET ρυθμίστε την ώστε να τη λαμβάνει από το .

XMLHttpRequest.responseTypeblob για να δώσετε εντολή στα δυαδικά δεδομένα που θα ληφθούν.

XMLHttpRequest.onload Δεδομένου ότι η διαδικασία μετά την ολοκλήρωση της λήψης δεδομένων μπορεί να περιγραφεί στην εκδήλωση, η διαδικασία μετά την ολοκλήρωση της λήψης γράφεται εδώ. Δεδομένου ότι τα δεδομένα έχουν μεταφορτωθεί μόνο στον πελάτη, το αρχείο δεν αποθηκεύεται στην πραγματικότητα τοπικά. Για να αποθηκεύσετε ένα αρχείο τοπικά, μπορείτε να προσθέσετε μια ετικέτα που a περιέχει ψευδοδεδομένα και να το κάνετε να συμπεριφέρεται σαν να είχατε κάνει κλικ σε έναν σύνδεσμο και να είχατε αποθηκεύσει το αρχείο. Τα δεδομένα εκείνη τη στιγμή μπορούν να window.URL.createObjectURL μετατραπούν σε διεύθυνση URL από τη συνάρτηση, ώστε href να μπορείτε να τα ορίσετε και να τα κάνετε να λειτουργούν.

Το όνομα αρχείου που θα αποθηκευτεί μπορεί να ανακτηθεί από την κεφαλίδα απόκρισης, εάν περιλαμβάνεται στην απόκριση από το Content-Disposition διακομιστή. Δεδομένου ότι είναι λίγο περίπλοκο να αποκτηθεί, νομίζω ότι ο κώδικας πρέπει να χρησιμοποιηθεί ως έχει. Εάν το όνομα αρχείου δεν καθορίζεται στο διακομιστή, δεν μπορεί να βοηθηθεί, επομένως νομίζω ότι θα οριστεί στο προεπιλεγμένο όνομα αρχείου ή στο όνομα αρχείου στο τέλος της διαδρομής URL.

Δεδομένου ότι αυτή τη φορά το εμφανίζω μόνο στην κονσόλα μετά την αποθήκευση του αρχείου, νομίζω ότι η επιθυμητή λειτουργία μπορεί να εκτελεστεί ξαναγράφοντας αυτό το μέρος με αυθαίρετο κώδικα.

Μόλις περιγραφεί η διαδικασία λήψης δεδομένων, το τελευταίο πράγμα που θέλουμε να κάνουμε είναι XMLHttpRequest.send να καλέσουμε μια λειτουργία για να ξεκινήσουμε πραγματικά το αίτημα.

Λήψη συνδέσμου εκτέλεσης

Ο κ. / Ms. Code παρέχει συνδέσμους προς το μοτίβο της απευθείας λήψης του αρχείου και το μοτίβο της λήψης του με Javascript. a Μπορείτε να γράψετε τη διεύθυνση URL απευθείας στην href ετικέτα, αλλά αν γράψετε τα ακόλουθα στο ASP.NET Core, η διεύθυνση URL θα επεκταθεί αυτόματα href σε .

Σελίδες ξυραφιών : Pages/Index.cshtml

<ul>
  <li><a asp-page-handler="Download">ダウンロード (Javascript なし)</a></li>
  <li><a asp-page-handler="Download" id="download">ダウンロード (Javascript あり)</a></li>
</ul>

MVC : Προβολές/Αρχική σελίδα/Index.cshtml

<ul>
  <li><a asp-controller="Home" asp-action="Download">ダウンロード (Javascript なし)</a></li>
  <li><a asp-controller="Home" asp-action="Download" id="download">ダウンロード (Javascript あり)</a></li>
</ul>