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.

Razor Страницы : Страниц/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 или 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 расширится до .

Страницы Razor : 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 : Views/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>