Javascript за извършване на обработка след изтегляне на файл

Страницата се актуализира :
Дата на създаване на страница :

Среда за проверка на експлоатацията

Визуално студио
  • Визуално студио 2022
ASP.NET Ядро
  • 8.0 (Разпр страници, MVC)
Уеб браузъри
  • Край 119

Работна среда

Visual Studio (ако включите и сървърни програми)
  • Визуално студио 2022
ASP.NET Core (ако включва и сървърни програми)
  • 8.0 (Разпр страници, MVC)
Уеб браузъри
  • Ръб
  • Гугъл Хром
  • Други браузъри (не всички са проверени)

(* Основното тяло на този съвет е процесът от страна на клиента, така че сървърната страна може да бъде всичко)

Отначало

Основният фокус на тези съвети е клиентската програма (Javascript), а сървърната програма е там само за изтегляне на файлове. Следователно няма значение каква е сървърната програма, стига да може да ви накара да изтеглите файла.

Накарайте потребителите да изтеглят файлове, когато те са достъпни на сървъра

Mr./Ms. ви позволява да изтегляте файлове, когато получите заявка. По това време умишлено чакаме определен период от време на сървъра, за да е лесно да разберем началото и края на изтеглянето.

Ето какво се случва от страна на сървъра на Razor Pages и MVC: Можете да го внедрите в други проекти, като например Web API.

Бръснач Страници : Страници/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 : Колетолери / 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 произходът на асинхронната обработка. Можете също да използвате функциите jQuery ajax или API Fetch.

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 ще се разшири до .

Бръснач Страници : Страници/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 : Прегледи/Начало/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>