Javascript za izvedbo obdelave po prenosu datoteke

Stran posodobljena :
Datum ustvarjanja strani :

Okolje za preverjanje delovanja

Visual Studio
  • Visual Studio 2022
ASP.NET jedro
  • 8.0 (Razpr strani, MVC)
Spletni brskalniki
  • Edge 119

Delovno okolje

Visual Studio (če vključite tudi strežniške programe)
  • Visual Studio 2022
ASP.NET Core (če vključuje tudi strežniške programe)
  • 8.0 (Razpr strani, MVC)
Spletni brskalniki
  • Rob
  • Google Chrome
  • Drugi brskalniki (niso vsi preverjeni)

(* Glavno telo tega nasveta je proces na strani odjemalca, zato je stran strežnika lahko karkoli)

Sprva

Glavni poudarek teh nasvetov je odjemalski program (Javascript), strežniški program pa je tam samo za prenos datotek. Zato ni pomembno, kaj je strežniški program, če lahko prenesete datoteko.

Uporabniki naj prenesejo datoteke, ko dostopajo do strežnika

G./Ms. vam omogoča prenos datotek, ko prejmete zahtevo. Takrat namerno čakamo določen čas na strežniku, tako da je enostavno razumeti začetek in konec prenosa.

Evo, kaj se zgodi na strežniški strani strani Razor Pages in MVC: Implementirate ga lahko v drugih projektih, kot je spletni API.

Britvice strani : Strani/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");
    }
  }
}

Obdelava strank

Običajno datoteko prenesete z dostopom do določenega URL-ja v spletnem brskalniku. Če želite nekaj narediti po končanem prenosu, lahko prenos zaženete z Javascriptom.

Obstaja veliko načinov za to, vendar bomo v tem primeru uporabili , kar je tudi XMLHttpRequest izvor asinhrone obdelave. Uporabite lahko tudi funkcije jQuery ajax ali API za pridobivanje.

ahref URL za prenos je zapisan v oznako in id postopek se izvede, ko kliknete tistega, ki je nastavljendownload.

$('#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 Običajno, če pustite element kliknjen, se bo privzeti postopek prenosa premaknil, zato e.preventDefault(); pozivamo, da onemogočite privzeti postopek.

href Pridobite URL za prenos iz in XMLHttpRequest GET ga nastavite tako, da ga dobite od .

XMLHttpRequest.responseTypeblob za navodila za prenos binarnih podatkov.

XMLHttpRequest.onload Ker je postopek po končanem prenosu podatkov mogoče opisati v primeru, je postopek po končanem prenosu napisan tukaj. Ker so bili podatki preneseni samo v odjemalca, datoteka dejansko ni shranjena lokalno. Če želite datoteko shraniti lokalno, lahko dodate oznako, ki vsebuje psevdopodatke, in poskrbite, da se bo obnašala, kot da a ste kliknili povezavo in shranili datoteko. Funkcije lahko window.URL.createObjectURL podatke takrat pretvorijo v URL, tako href da jih lahko nastavite in poskrbite, da delujejo.

Ime datoteke, ki jo želite shraniti, lahko pridobite iz glave odgovora, če je vključena v odgovor strežnika Content-Disposition . Ker je pridobitev nekoliko zapletena, mislim, da je treba kodo uporabljati tako, kot je. Če ime datoteke ni določeno na strežniku, mu ni mogoče pomagati, zato mislim, da bo nastavljeno na privzeto ime datoteke ali ime datoteke na koncu poti URL.

Ker ga tokrat prikažem samo v konzoli po shranjevanju datoteke, mislim, da je želeno operacijo mogoče izvesti s ponovnim pisanjem tega dela s poljubno kodo.

Ko je postopek prenosa podatkov opisan, je zadnja stvar, ki jo želimo storiti XMLHttpRequest.send , poklicati funkcijo, da dejansko zaženemo zahtevo.

Povezava za prenos zagona

G./Ms. Code ponuja povezave do vzorca neposrednega prenosa datoteke in vzorca prenosa z Javascriptom. a URL lahko zapišete neposredno v href oznako, če pa v ASP.NET jedru zapišete naslednje, se bo URL samodejno href razširil na .

Britvice strani : 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 : Ogledi/Domov/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>