Javascript do wykonywania przetwarzania po pobraniu pliku

Strona zaktualizowana :
Data utworzenia strony :

Środowisko weryfikacji działania

Visual Studio
  • informacji o wersji Visual Studio 2022
ASP.NET Rdzeń
  • 8.0 (strony Razpr, MVC)
Przeglądarki internetowe
  • Krawędź 119

Środowisko pracy

Visual Studio (jeśli dołączasz również programy serwerowe)
  • informacji o wersji Visual Studio 2022
ASP.NET Core (jeśli zawiera również programy serwerowe)
  • 8.0 (strony Razpr, MVC)
Przeglądarki internetowe
  • Brzeg
  • Google Chrome
  • Inne przeglądarki (nie wszystkie zaznaczone)

(* Główną częścią tej porady jest proces po stronie klienta, więc strona serwera może być dowolna)

Na początku

Głównym celem tych wskazówek jest program kliencki (Javascript), a program serwerowy służy tylko do pobierania plików. Dlatego nie ma znaczenia, jaki jest program serwera, o ile może zmusić Cię do pobrania pliku.

Poproś użytkowników o pobieranie plików, gdy są one dostępne na serwerze

Pan/Pani umożliwia pobieranie plików po otrzymaniu prośby. W tym czasie celowo czekamy na serwerze przez określony czas, aby łatwo było zrozumieć początek i koniec pobierania.

Oto, co dzieje się po stronie serwera Razor Pages i MVC: Można go zaimplementować w innych projektach, takich jak internetowy interfejs API.

Strony brzytwy : Strony/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");
    }
  }
}

Przetwarzanie klientów

Zwykle pobierasz plik, uzyskując dostęp do określonego adresu URL w przeglądarce internetowej. Jeśli chcesz coś zrobić po zakończeniu pobierania, możesz uruchomić pobieranie za pomocą JavaScript.

Można to zrobić na wiele sposobów, ale w tym przypadku użyjemy , który jest również XMLHttpRequest źródłem przetwarzania asynchronicznego. Możesz także użyć funkcji ajax jQuery lub interfejsu API pobierania.

ahref Adres URL pobierania jest zapisywany w tagu, a id proces jest wykonywany po kliknięciu ustawionego nadownload.

$('#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 Zwykle, jeśli pozostawisz kliknięty element, domyślny proces pobierania zostanie przeniesiony, więc e.preventDefault(); wywołujemy, aby wyłączyć domyślny proces.

href Pobierz adres URL pobierania z i XMLHttpRequest GET ustaw go tak, aby pobierał go z .

XMLHttpRequest.responseTypeblob, aby poinstruować dane binarne, które mają zostać pobrane.

XMLHttpRequest.onload Ponieważ proces po zakończeniu pobierania danych można opisać w zdarzeniu, proces po zakończeniu pobierania jest zapisany tutaj. Ponieważ dane zostały pobrane tylko do klienta, plik nie jest w rzeczywistości przechowywany lokalnie. Aby zapisać plik lokalnie, możesz dodać znacznik zawierający pseudodane i sprawić, by a zachowywał się tak, jakbyś kliknął łącze i zapisał plik. Dane w tym czasie mogą window.URL.createObjectURL zostać przekonwertowane na adres URL przez funkcję, dzięki czemu href można ją ustawić i sprawić, by działała.

Nazwę pliku, który ma zostać zapisany, można pobrać z nagłówka odpowiedzi, jeśli jest ona zawarta w odpowiedzi z serwera Content-Disposition . Ponieważ jest to trochę skomplikowane do zdobycia, myślę, że kod powinien być używany tak, jak jest. Jeśli nazwa pliku nie jest podana na serwerze, nic na to nie poradzisz, więc myślę, że zostanie ustawiona na domyślną nazwę pliku lub nazwę pliku na końcu ścieżki URL.

Ponieważ tym razem wyświetlam go dopiero w konsoli po zapisaniu pliku, myślę, że żądaną operację można wykonać, przepisując tę część dowolnym kodem.

Po opisaniu procesu pobierania danych ostatnią rzeczą, jaką chcemy zrobić, jest XMLHttpRequest.send wywołanie funkcji, aby faktycznie uruchomić żądanie.

Link do pobrania

Mr./Ms. Code podaje linki do wzorca pobierania pliku bezpośrednio oraz wzorca pobierania go za pomocą Javascript. a Możesz wpisać adres URL bezpośrednio w tagu href , ale jeśli napiszesz następujące polecenie w ASP.NET Core, adres URL zostanie automatycznie href rozwinięty do .

Razor Strony: 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>