Javascript для виконання обробки після завантаження файлу

Сторінка оновлюється :
Дата створення сторінки :

Середовище перевірки роботи

Візуальна студія
  • Visual Studio 2022
ASP.NET Ядро
  • 8.0 (Razpr Pages, MVC)
Веб-браузери
  • Край 119

Робоче середовище

Visual Studio (якщо ви також включаєте серверні програми)
  • Visual Studio 2022
ASP.NET Core (якщо до його складу входять ще й серверні програми)
  • 8.0 (Razpr Pages, MVC)
Веб-браузери
  • Край
  • Google Chrome
  • Інші браузери (перевірено не всі)

(* Основною частиною цієї підказки є процес на стороні клієнта, тому сторона сервера може бути будь-якою)

Спочатку

Основна увага в цих порадах приділяється клієнтській програмі (Javascript), а серверна програма існує тільки для завантаження файлів. Тому не має значення, що це за програма-сервер, головне, щоб вона змусила вас завантажити файл.

Змушувати користувачів завантажувати файли, коли до них звертаються на сервері

Mr./Ms. дозволяє завантажувати файли, коли ви отримуєте запит. У цей час ми навмисно чекаємо певну кількість часу на сервері, щоб було легко зрозуміти початок і кінець завантаження.

Ось що відбувається на стороні сервера 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 є джерелом асинхронної обробки. Ви також можете використовувати функції jQuery ajax або Fetch API.

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 викликати функцію, щоб фактично запустити запит.

Посилання для завантаження

Mr./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 : Перегляди/Головна/Індекс.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>