Javascript a fájl letöltése utáni feldolgozás végrehajtásához

Oldal frissítve :
Oldal létrehozásának dátuma :

Művelet-ellenőrzési környezet

Visual Studio
  • Visual Studio 2022
ASP.NET mag
  • 8.0 (Razpr oldalak, MVC)
Webböngészők
  • 119. szél

Működési környezet

Visual Studio (ha kiszolgálóprogramokat is tartalmaz)
  • Visual Studio 2022
ASP.NET Core (ha kiszolgálóprogramokat is tartalmaz)
  • 8.0 (Razpr oldalak, MVC)
Webböngészők
  • Perem
  • Google Chrome
  • Más böngészők (nem mindegyik van bejelölve)

(* Ennek a tippnek a fő része a kliens oldali folyamat, így a szerver oldal bármi lehet)

Először

Ezeknek a tippeknek a fő hangsúlya az ügyfélprogram (Javascript), és a szerverprogram csak a fájlok letöltésére szolgál. Ezért nem számít, mi a szerverprogram, mindaddig, amíg le tudja tölteni a fájlt.

Kérje meg a felhasználókat, hogy töltsenek le fájlokat, amikor hozzáférnek hozzájuk a kiszolgálón

Mr./Ms. lehetővé teszi fájlok letöltését, amikor kérést kap. Abban az időben szándékosan várunk egy bizonyos időt a szerveren, hogy könnyen megértsük a letöltés kezdetét és végét.

Íme, mi történik a Razor Pages és az MVC szerver oldalán: Más projektekben, például a webes API-ban is megvalósíthatja.

Borotva oldalak : Oldalak/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");
    }
  }
}

Ügyfél feldolgozása

Általában egy fájlt úgy tölthet le, hogy hozzáfér egy megadott URL-hez egy webböngészőben. Ha valamit tenni szeretne a letöltés befejezése után, futtathatja a letöltést Javascript segítségével.

Ennek számos módja van, de ebben az esetben a -t fogjuk használni, amely az aszinkron feldolgozás eredete is XMLHttpRequest . Használhatja a jQuery ajax függvényeket vagy a Fetch API-t is.

ahref A letöltési URL-cím be van írva a címkébe, és id a folyamat akkor kerül végrehajtásra, amikor rákattint a beállított download URL-re.

$('#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 Általában, ha hagyja lenyomva az elemet, az alapértelmezett letöltési folyamat mozog, ezért e.preventDefault(); felhívjuk az alapértelmezett folyamat letiltását.

href Szerezze be a letöltési URL-címet innen, és XMLHttpRequest GET állítsa be, hogy a .

XMLHttpRequest.responseTypeblob a letöltendő bináris adatok utasításához.

XMLHttpRequest.onload Mivel az adatletöltés befejezése utáni folyamat leírható az eseményben, a letöltés befejezése utáni folyamat itt van írva. Mivel az adatokat csak az ügyfélre töltötték le, a fájl valójában nem helyileg tárolódik. Ha helyileg szeretne menteni egy fájlt, hozzáadhat egy címkét, amely pszeudoadatokat tartalmaz, és beállíthatja, hogy a úgy viselkedjen, mintha egy hivatkozásra kattintott volna, és mentette volna a fájlt. Az akkori window.URL.createObjectURL adatokat a függvény URL-címmé konvertálhatja, így href beállíthatja és működtetheti.

A mentendő fájlnév leolvasható a válasz fejlécéből, ha az szerepel a Content-Disposition kiszolgálótól érkező válaszban. Mivel egy kicsit bonyolult megszerezni, úgy gondolom, hogy a kódot úgy kell használni, ahogy van. Ha a fájlnév nincs megadva a szerveren, akkor nem lehet segíteni, ezért úgy gondolom, hogy az alapértelmezett fájlnévre vagy az URL-útvonal végén lévő fájlnévre lesz beállítva.

Mivel ezúttal csak a fájl mentése után jelenítem meg a konzolban, úgy gondolom, hogy a kívánt művelet végrehajtható ennek a résznek tetszőleges kóddal történő átírásával.

Az adatletöltési folyamat leírása után az utolsó dolog, amit meg akarunk tenni, hogy XMLHttpRequest.send meghívunk egy függvényt a kérés tényleges elindításához.

Letöltés futtatása hivatkozás

Mr./Ms. Code linkeket biztosít a fájl közvetlen letöltésének mintájához és a Javascripttel történő letöltés mintájához. a Az URL-címet közvetlenül a href címkébe is írhatja, de ha a következőt írja be a ASP.NET Core-ba, az URL-cím automatikusan href kibővül a következőre: .

Borotva oldalak : 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 : Nézetek/Kezdőlap/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>