Javascript để thực hiện xử lý sau khi tải xuống tệp
Môi trường xác minh hoạt động
- Visual Studio
-
- Visual Studio 2022
- Lõi ASP.NET
-
- 8.0 (Trang Razpr, MVC)
- Trình duyệt web
-
- Cạnh 119
Môi trường hoạt động
- Visual Studio (nếu bạn cũng bao gồm các chương trình máy chủ)
-
- Visual Studio 2022
- ASP.NET Core (nếu nó cũng bao gồm các chương trình máy chủ)
-
- 8.0 (Trang Razpr, MVC)
- Trình duyệt web
-
- Cạnh
- Google Chrome
- Các trình duyệt khác (không phải tất cả đều được chọn)
(* Phần chính của mẹo này là quy trình phía máy khách, vì vậy phía máy chủ có thể là bất cứ thứ gì)
Lúc đầu
Trọng tâm chính của các mẹo này là chương trình máy khách (Javascript) và chương trình máy chủ chỉ ở đó để tải xuống tệp. Do đó, không quan trọng chương trình máy chủ là gì, miễn là nó có thể khiến bạn tải xuống tệp.
Yêu cầu người dùng tải xuống tệp khi chúng được truy cập trên máy chủ
Ông / Bà cho phép bạn tải xuống các tệp khi bạn nhận được yêu cầu. Khi đó, chúng tôi cố tình đợi một khoảng thời gian nhất định trên máy chủ để dễ hiểu khi bắt đầu và kết thúc quá trình tải xuống.
Đây là những gì xảy ra ở phía máy chủ của Razor Pages và MVC: Bạn có thể triển khai nó trong các dự án khác, chẳng hạn như API Web.
Trang dao cạo: Trang/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");
}
}
}
Xử lý khách hàng
Thông thường, bạn tải xuống tệp bằng cách truy cập URL được chỉ định trong trình duyệt web. Nếu bạn muốn làm điều gì đó sau khi quá trình tải xuống hoàn tất, bạn có thể chạy tải xuống bằng Javascript.
Có nhiều cách để làm điều này, nhưng trong trường hợp này, chúng tôi sẽ sử dụng , đó cũng XMLHttpRequest
là nguồn gốc của xử lý không đồng bộ.
Bạn cũng có thể sử dụng các hàm ajax jQuery hoặc API Fetch.
a
href
URL tải xuống được ghi trong thẻ và id
quá trình được thực thi khi nhấp vào URL được đặt thànhdownload
.
$('#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
Thông thường, nếu bạn để phần tử được nhấp, quá trình tải xuống mặc định sẽ di chuyển, vì vậy e.preventDefault();
chúng tôi gọi để vô hiệu hóa quá trình mặc định.
href
Lấy URL tải xuống từ và XMLHttpRequest
GET
đặt nó để lấy nó từ .
XMLHttpRequest.responseType
blob
để hướng dẫn dữ liệu nhị phân được tải xuống.
XMLHttpRequest.onload
Vì quá trình sau khi tải xuống dữ liệu hoàn tất có thể được mô tả trong sự kiện, quá trình sau khi tải xuống hoàn tất được viết ở đây.
Vì dữ liệu chỉ được tải xuống máy khách, tệp không thực sự được lưu trữ cục bộ.
Để lưu tệp cục bộ, bạn có thể thêm thẻ a
chứa dữ liệu giả và làm cho thẻ hoạt động như thể bạn đã nhấp vào liên kết và lưu tệp.
Dữ liệu tại thời điểm đó có thể window.URL.createObjectURL
được chuyển đổi thành URL bằng hàm, vì vậy href
bạn có thể đặt nó thành và làm cho nó hoạt động.
Tên tệp được lưu có thể được truy xuất từ tiêu đề phản hồi nếu nó được bao gồm trong phản hồi từ Content-Disposition
máy chủ.
Vì nó hơi phức tạp để có được, tôi nghĩ rằng mã nên được sử dụng như hiện tại.
Nếu tên tệp không được chỉ định trên máy chủ, nó không thể được trợ giúp, vì vậy tôi nghĩ rằng nó sẽ được đặt thành tên tệp mặc định hoặc tên tệp ở cuối đường dẫn URL.
Vì lần này tôi chỉ hiển thị nó trong bảng điều khiển sau khi lưu tệp, tôi nghĩ rằng thao tác mong muốn có thể được thực thi bằng cách viết lại phần này bằng mã tùy ý.
Khi quá trình tải xuống dữ liệu được mô tả, điều cuối cùng chúng ta muốn làm là XMLHttpRequest.send
gọi một hàm để thực sự bắt đầu yêu cầu.
Liên kết chạy tải xuống
Mr./Ms. Code cung cấp các liên kết đến mẫu tải xuống tệp trực tiếp và mẫu tải xuống bằng Javascript.
a
Bạn có thể viết URL trực tiếp vào href
thẻ nhưng nếu bạn viết như sau trong ASP.NET Core, URL sẽ tự động href
mở rộng thành .
Trang dao cạo: 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 : Lượt xem/Trang chủ/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>