Javascript för att utföra bearbetning efter nedladdning av en fil

Sidan uppdaterad :
Datum för skapande av sida :

Miljö för verifiering av åtgärder

Visuell studio
  • Visual Studio 2022
ASP.NET kärna
  • 8.0 (Razpr-sidor, MVC)
Webbläsare
  • Kant 119

Omvärld

Visual Studio (om du även inkluderar serverprogram)
  • Visual Studio 2022
ASP.NET Core (om den även innehåller serverprogram)
  • 8.0 (Razpr-sidor, MVC)
Webbläsare
  • Kant
  • Google Chrome
  • Andra webbläsare (inte alla kontrollerade)

(* Huvuddelen av detta tips är processen på klientsidan, så serversidan kan vara vad som helst)

Först

Huvudfokus för dessa tips är klientprogrammet (Javascript), och serverprogrammet är bara till för att ladda ner filer. Därför spelar det ingen roll vad serverprogrammet är, så länge det kan få dig att ladda ner filen.

Låt användarna ladda ned filer när de används på servern

Mr./Ms. låter dig ladda ner filer när du får en begäran. Vid den tiden väntar vi medvetet en viss tid på servern så att det är lätt att förstå början och slutet av nedladdningen.

Här är vad som händer på serversidan av Razor Pages och MVC: Du kan implementera den i andra projekt, till exempel webb-API.

Razor Sidor : Sidor/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");
    }
  }
}

Bearbetning av klienter

Normalt laddar du ned en fil genom att komma åt en angiven URL i en webbläsare. Om du vill göra något efter att nedladdningen är klar kan du köra nedladdningen med Javascript.

Det finns många sätt att göra detta, men i det här fallet kommer vi att använda , som också XMLHttpRequest är ursprunget till asynkron bearbetning. Du kan också använda jQuery ajax-funktioner eller Fetch API.

ahref Nedladdnings-URL:en skrivs i taggen och id processen utförs när du klickar på den som är inställd på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 Normalt, om du lämnar elementet klickat, kommer standardnedladdningsprocessen att flyttas, så e.preventDefault(); vi ringer för att inaktivera standardprocessen.

href Hämta nedladdnings-URL:en från och XMLHttpRequest GET ställ in den för att hämta den från .

XMLHttpRequest.responseTypeblob för att instruera binära data som ska laddas ner.

XMLHttpRequest.onload Eftersom processen efter att datanedladdningen har slutförts kan beskrivas i händelsen, skrivs processen efter att nedladdningen är klar här. Eftersom data bara har laddats ner till klienten lagras filen inte lokalt. Om du vill spara en fil lokalt kan du lägga till en tagg som a innehåller pseudodata och få den att bete sig som om du hade klickat på en länk och sparat filen. Data vid den tidpunkten kan window.URL.createObjectURL konverteras till en URL av funktionen, så href att du kan ställa in den på och få den att fungera.

Filnamnet som ska sparas kan hämtas från svarshuvudet om det ingår i svaret från Content-Disposition servern. Eftersom det är lite komplicerat att skaffa tycker jag att koden ska användas som den är. Om filnamnet inte anges på servern kan det inte hjälpas, så jag tror att det kommer att ställas in på standardfilnamnet eller filnamnet i slutet av URL-sökvägen.

Eftersom jag den här gången bara visar den i konsolen efter att ha sparat filen, tror jag att den önskade operationen kan utföras genom att skriva om den här delen med godtycklig kod.

När datanedladdningsprocessen har beskrivits är det sista vi vill göra att XMLHttpRequest.send anropa en funktion för att faktiskt starta begäran.

Ladda ner körningslänk

Mr./Ms. Code ger länkar till mönstret för att ladda ner filen direkt och mönstret för att ladda ner den med Javascript. a Du kan skriva URL:en direkt i taggen href , men om du skriver följande i ASP.NET Core expanderas URL:en automatiskt href till .

Razor Sidor: Sidor/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: Vyer/Hem/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>