Javascript untuk melakukan pemrosesan setelah mengunduh file
Lingkungan verifikasi operasi
- Visual Studio
-
- Visual Studio 2022
- ASP.NET Inti
-
- 8.0 (Halaman Razpr, MVC)
- Browser Web
-
- Tepi 119
Lingkungan operasi
- Visual Studio (jika Anda juga menyertakan program server)
-
- Visual Studio 2022
- ASP.NET Core (jika juga termasuk program server)
-
- 8.0 (Halaman Razpr, MVC)
- Browser Web
-
- Pinggir
- Google Chrome
- Browser lain (tidak semua dicentang)
(* Bagian utama dari tip ini adalah proses sisi klien, sehingga sisi server bisa apa saja)
Pada awalnya
Fokus utama dari tips ini adalah program klien (Javascript), dan program server hanya ada untuk mengunduh file. Oleh karena itu, tidak masalah apa program servernya, asalkan dapat membuat Anda mengunduh file.
Minta pengguna mengunduh file saat diakses di server
Mr./Ms. memungkinkan Anda mengunduh file saat Anda menerima permintaan. Pada saat itu, kami sengaja menunggu beberapa waktu di server sehingga mudah untuk memahami awal dan akhir unduhan.
Inilah yang terjadi di sisi server Razor Pages dan MVC: Anda dapat menerapkannya di proyek lain, seperti Web API.
Razor Pages : Halaman/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");
}
}
}
Pemrosesan klien
Biasanya, Anda mengunduh file dengan mengakses URL tertentu di browser web. Jika Anda ingin melakukan sesuatu setelah unduhan selesai, Anda dapat menjalankan unduhan dengan Javascript.
Ada banyak cara untuk melakukan ini, tetapi dalam hal ini, kami akan menggunakan , yang juga XMLHttpRequest
merupakan asal mula pemrosesan asinkron.
Anda juga dapat menggunakan fungsi ajax jQuery atau Fetch API.
a
href
URL unduhan ditulis dalam tag dan id
proses dijalankan ketika yang diatur ke download
diklik.
$('#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
Biasanya, jika Anda membiarkan elemen diklik, proses pengunduhan default akan bergerak, jadi e.preventDefault();
kami memanggil untuk menonaktifkan proses default.
href
Dapatkan URL unduhan dari dan XMLHttpRequest
GET
atur untuk mendapatkannya dari .
XMLHttpRequest.responseType
blob
untuk menginstruksikan data biner yang akan diunduh.
XMLHttpRequest.onload
Karena proses setelah pengunduhan data selesai dapat dijelaskan dalam acara, proses setelah pengunduhan selesai ditulis di sini.
Karena data hanya diunduh ke klien, file tersebut sebenarnya tidak disimpan secara lokal.
Untuk menyimpan file secara lokal, Anda dapat menambahkan tag yang a
berisi pseudo-data dan membuatnya berperilaku seolah-olah Anda telah mengklik tautan dan menyimpan file.
Data pada saat itu dapat window.URL.createObjectURL
dikonversi ke URL oleh fungsi, sehingga href
Anda dapat mengaturnya dan membuatnya berfungsi.
Nama file yang akan disimpan dapat diambil dari header respons jika disertakan dalam respons dari Content-Disposition
server.
Karena agak rumit untuk memperolehnya, saya pikir kode tersebut harus digunakan apa adanya.
Jika nama file tidak ditentukan di server, itu tidak dapat membantu, jadi saya pikir itu akan diatur ke nama file default atau nama file di akhir jalur URL.
Karena saat ini saya hanya menampilkannya di konsol setelah menyimpan file, saya pikir operasi yang diinginkan dapat dijalankan dengan menulis ulang bagian ini dengan kode arbitrer.
Setelah proses pengunduhan data dijelaskan, hal terakhir yang ingin kita lakukan adalah XMLHttpRequest.send
memanggil fungsi untuk benar-benar memulai permintaan.
Unduh tautan jalankan
Mr./Ms. Code menyediakan tautan ke pola mengunduh file secara langsung dan pola mengunduhnya dengan Javascript.
a
Anda dapat menulis URL langsung di href
tag , tetapi jika Anda menulis yang berikut ini di ASP.NET Core, URL akan secara otomatis href
diperluas ke .
Razor Halaman : 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 : Tampilan/Beranda/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>