Javascript per realitzar el processament després de descarregar un fitxer

Pàgina actualitzada :
Data de creació de la pàgina :

Entorn de verificació d'operacions

Estudi visual
  • Estudi visual 2022
ASP.NET Nucli
  • 8.0 (Razpr Pàgines, MVC)
Navegadors web
  • Vora 119

Entorn operatiu

Visual Studio (si també inclou programes de servidor)
  • Estudi visual 2022
ASP.NET Core (si també inclou programes servidor)
  • 8.0 (Razpr Pàgines, MVC)
Navegadors web
  • Vora
  • Google Chrome
  • Altres navegadors (no tots marcats)

(* El cos principal d'aquest consell és el procés del costat del client, de manera que el costat del servidor pot ser qualsevol cosa)

Al principi

El focus principal d'aquests consells és el programa client (Javascript), i el programa servidor només hi és per descarregar fitxers. Per tant, no importa quin sigui el programa servidor, sempre que us pugui fer descarregar el fitxer.

Feu que els usuaris descarreguin fitxers quan s'hi accedeixi al servidor

Mr./Ms. li permet descarregar arxius quan rep una sol·licitud. En aquest moment, esperem deliberadament una certa quantitat de temps al servidor perquè sigui fàcil entendre l'inici i el final de la descàrrega.

Això és el que passa al costat del servidor de Razor Pages i MVC: Podeu implementar-lo en altres projectes, com ara l'API web.

Navalles d'afaitar : pàgines/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");
    }
  }
}

Tramitació de clients

Normalment, baixeu un fitxer accedint a un URL especificat en un navegador web. Si voleu fer alguna cosa un cop finalitzada la descàrrega, podeu executar la descàrrega amb Javascript.

Hi ha moltes maneres de fer-ho, però en aquest cas, utilitzarem , que també XMLHttpRequest és l'origen del processament asíncron. També podeu utilitzar les funcions ajax de jQuery o l'API Fetch.

ahref L'URL de baixada s'escriu a l'etiqueta i id el procés s'executa quan es fa clic al que s'ha definit adownload.

$('#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 Normalment, si deixeu l'element clicat, el procés de descàrrega per defecte es mourà, de manera que e.preventDefault(); cridem a desactivar el procés per defecte.

href Obteniu l'URL de descàrrega i XMLHttpRequest GET configureu-lo per obtenir-lo de .

XMLHttpRequest.responseTypeblob per indicar les dades binàries que s'han de descarregar.

XMLHttpRequest.onload Com que el procés un cop finalitzada la descàrrega de dades es pot descriure a l'esdeveniment, el procés un cop finalitzada la descàrrega s'escriu aquí. Com que les dades només s'han descarregat al client, el fitxer no s'emmagatzema localment. Per desar un fitxer localment, podeu afegir una etiqueta que contingui pseudodades i fer que a es comporti com si haguéssiu fet clic en un enllaç i l'haguéssiu desat. Les dades en aquell moment es poden window.URL.createObjectURL convertir en un URL mitjançant la funció, de manera que href podeu configurar-les i fer-les funcionar.

El nom del fitxer a desar es pot recuperar de la capçalera de resposta si s'inclou a la resposta del Content-Disposition servidor. Com que és una mica complicat d'adquirir, crec que el codi s'hauria d'utilitzar tal com està. Si el nom del fitxer no s'especifica al servidor, no es pot ajudar, de manera que crec que s'establirà al nom de fitxer predeterminat o al nom del fitxer al final de la ruta URL.

Com que aquesta vegada només el mostro a la consola després de desar el fitxer, crec que l'operació desitjada es pot executar reescrivint aquesta part amb codi arbitrari.

Un cop descrit el procés de descàrrega de dades, l'últim que volem fer és XMLHttpRequest.send trucar a una funció per iniciar realment la sol·licitud.

Descarregar enllaç d'execució

Mr./Ms. Code proporciona enllaços al patró de descàrrega directa del fitxer i al patró de descàrrega amb Javascript. a Podeu escriure l'URL directament a l'etiqueta href , però si escriviu el següent a ASP.NET nucli, l'URL s'expandirà automàticament href a .

Navalles d'afaitar : pàgines/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 : Vistes/Inici/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>