Javascript untuk melakukan pemrosesan setelah mengunduh file

Halaman Diperbarui :
Tanggal pembuatan halaman :

Lingkungan verifikasi operasi

Visual Studio
  • Visual Studio 2022
ASP.NET Inti
  • 8.0 (Halaman Razpr, MVC)
Browser Web
  • Tepi 119

Lingkungan operasi

Visual Studio (jika Anda juga menyertakan program server)
  • Visual Studio 2022
ASP.NET Core (jika juga termasuk program server)
  • 8.0 (Halaman Razpr, MVC)
Browser Web
  • Pinggir
  • Google Chrome
  • Browser lain (tidak semua dicentang)

(* Bagian utama dari tip ini adalah proses sisi klien, sehingga sisi server bisa apa saja)

Pada awalnya

Fokus utama dari tips ini adalah program klien (Javascript), dan program server hanya ada untuk mengunduh file. Oleh karena itu, tidak masalah apa program servernya, asalkan dapat membuat Anda mengunduh file.

Minta pengguna mengunduh file saat diakses di server

Mr./Ms. memungkinkan Anda mengunduh file saat Anda menerima permintaan. Pada saat itu, kami sengaja menunggu beberapa waktu di server sehingga mudah untuk memahami awal dan akhir unduhan.

Inilah yang terjadi di sisi server Razor Pages dan MVC: Anda dapat menerapkannya di proyek lain, seperti Web API.

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

Pemrosesan klien

Biasanya, Anda mengunduh file dengan mengakses URL tertentu di browser web. Jika Anda ingin melakukan sesuatu setelah unduhan selesai, Anda dapat menjalankan unduhan dengan Javascript.

Ada banyak cara untuk melakukan ini, tetapi dalam hal ini, kami akan menggunakan , yang juga XMLHttpRequest merupakan asal mula pemrosesan asinkron. Anda juga dapat menggunakan fungsi ajax jQuery atau Fetch API.

ahref URL unduhan ditulis dalam tag dan id proses dijalankan ketika yang diatur ke download diklik.

$('#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 Biasanya, jika Anda membiarkan elemen diklik, proses pengunduhan default akan bergerak, jadi e.preventDefault(); kami memanggil untuk menonaktifkan proses default.

href Dapatkan URL unduhan dari dan XMLHttpRequest GET atur untuk mendapatkannya dari .

XMLHttpRequest.responseTypeblob untuk menginstruksikan data biner yang akan diunduh.

XMLHttpRequest.onload Karena proses setelah pengunduhan data selesai dapat dijelaskan dalam acara, proses setelah pengunduhan selesai ditulis di sini. Karena data hanya diunduh ke klien, file tersebut sebenarnya tidak disimpan secara lokal. Untuk menyimpan file secara lokal, Anda dapat menambahkan tag yang a berisi pseudo-data dan membuatnya berperilaku seolah-olah Anda telah mengklik tautan dan menyimpan file. Data pada saat itu dapat window.URL.createObjectURL dikonversi ke URL oleh fungsi, sehingga href Anda dapat mengaturnya dan membuatnya berfungsi.

Nama file yang akan disimpan dapat diambil dari header respons jika disertakan dalam respons dari Content-Disposition server. Karena agak rumit untuk memperolehnya, saya pikir kode tersebut harus digunakan apa adanya. Jika nama file tidak ditentukan di server, itu tidak dapat membantu, jadi saya pikir itu akan diatur ke nama file default atau nama file di akhir jalur URL.

Karena saat ini saya hanya menampilkannya di konsol setelah menyimpan file, saya pikir operasi yang diinginkan dapat dijalankan dengan menulis ulang bagian ini dengan kode arbitrer.

Setelah proses pengunduhan data dijelaskan, hal terakhir yang ingin kita lakukan adalah XMLHttpRequest.send memanggil fungsi untuk benar-benar memulai permintaan.

Unduh tautan jalankan

Mr./Ms. Code menyediakan tautan ke pola mengunduh file secara langsung dan pola mengunduhnya dengan Javascript. a Anda dapat menulis URL langsung di href tag , tetapi jika Anda menulis yang berikut ini di ASP.NET Core, URL akan secara otomatis href diperluas ke .

Razor Halaman : 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 : Tampilan/Beranda/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>