Javascript zur Verarbeitung nach dem Herunterladen einer Datei

Diese Seite wurde aktualisiert :
Erstellungsdatum der Seite :

Umgebung zur Betriebsüberprüfung

Visuelles Studio
  • Visual Studio 2022
ASP.NET Kern
  • 8.0 (Razpr Pages, MVC)
Webbrowser
  • Edge 119

Betriebsumgebung

Visual Studio (wenn Sie auch Serverprogramme einschließen)
  • Visual Studio 2022
ASP.NET Core (wenn auch Serverprogramme enthalten sind)
  • 8.0 (Razpr Pages, MVC)
Webbrowser
  • Rand
  • Google Chrome
  • Andere Browser (nicht alle aktiviert)

(* Der Hauptteil dieses Tipps ist der clientseitige Prozess, sodass die Serverseite alles sein kann)

Zuerst

Das Hauptaugenmerk dieser Tipps liegt auf dem Client-Programm (Javascript), und das Serverprogramm ist nur zum Herunterladen von Dateien da. Daher spielt es keine Rolle, um welches Serverprogramm es sich handelt, solange Sie die Datei herunterladen können.

Benutzer Dateien herunterladen lassen, wenn auf dem Server darauf zugegriffen wird

Herr/Frau ermöglicht es Ihnen, Dateien herunterzuladen, wenn Sie eine Anfrage erhalten. Zu diesem Zeitpunkt warten wir bewusst eine gewisse Zeit auf dem Server, damit Start und Ende des Downloads leicht nachvollzogen werden können.

Folgendes geschieht auf der Serverseite von Razor Pages und MVC: Sie können es in anderen Projekten implementieren, z. B. in der Web-API.

Razor Pages : Seiten/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");
    }
  }
}

Client-Verarbeitung

Normalerweise laden Sie eine Datei herunter, indem Sie in einem Webbrowser auf eine bestimmte URL zugreifen. Wenn Sie nach Abschluss des Downloads etwas tun möchten, können Sie den Download mit Javascript ausführen.

Es gibt viele Möglichkeiten, dies zu tun, aber in diesem Fall verwenden wir , was auch XMLHttpRequest der Ursprung der asynchronen Verarbeitung ist. Sie können auch jQuery-Ajax-Funktionen oder die Fetch-API verwenden.

ahref Die Download-URL wird in das Tag geschrieben und id der Prozess wird ausgeführt, wenn auf die auf festgelegte download URL geklickt wird.

$('#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 Wenn Sie das Element angeklickt lassen, wird der Standard-Download-Prozess normalerweise verschoben, daher e.preventDefault(); rufen wir auf, um den Standardprozess zu deaktivieren.

href Holen Sie sich die Download-URL von und XMLHttpRequest GET legen Sie sie so fest, dass sie von abgerufen wird.

XMLHttpRequest.responseTypeblob, um die herunterzuladenden Binärdaten anzuweisen.

XMLHttpRequest.onload Da der Prozess nach Abschluss des Datendownloads im Event beschrieben werden kann, wird hier der Prozess nach Abschluss des Downloads geschrieben. Da die Daten nur auf den Client heruntergeladen wurden, wird die Datei nicht wirklich lokal gespeichert. Um eine Datei lokal zu speichern, können Sie ein Tag hinzufügen, das Pseudodaten enthält, a und es so verhalten, als hätten Sie auf einen Link geklickt und die Datei gespeichert. Die Daten zu diesem Zeitpunkt können window.URL.createObjectURL von der Funktion in eine URL konvertiert werden, sodass href Sie sie festlegen und zum Laufen bringen können.

Der zu speichernde Dateiname kann aus dem Antwortheader abgerufen werden, wenn er in der Antwort des Content-Disposition Servers enthalten ist. Da es etwas kompliziert zu erwerben ist, denke ich, dass der Code so verwendet werden sollte, wie er ist. Wenn der Dateiname nicht auf dem Server angegeben ist, kann nicht geholfen werden, daher denke ich, dass er auf den Standarddateinamen oder den Dateinamen am Ende des URL-Pfads gesetzt wird.

Da ich es diesmal erst nach dem Speichern der Datei in der Konsole anzeige, denke ich, dass die gewünschte Operation ausgeführt werden kann, indem dieser Teil mit beliebigem Code umgeschrieben wird.

Sobald der Daten-Download-Prozess beschrieben ist, möchten XMLHttpRequest.send wir als letztes eine Funktion aufrufen, um die Anfrage tatsächlich zu starten.

Link zum Ausführen herunterladen

Mr./Ms. Code bietet Links zum Muster des direkten Herunterladens der Datei und zum Muster des Herunterladens mit Javascript. a Sie können die URL direkt in das href Tag schreiben, aber wenn Sie Folgendes in ASP.NET Core schreiben, wird die URL automatisch href auf erweitert.

Razor Pages: 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 : Ansichten/Home/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>