Javascript do wykonywania przetwarzania po pobraniu pliku
Środowisko weryfikacji działania
- Visual Studio
-
- informacji o wersji Visual Studio 2022
- ASP.NET Rdzeń
-
- 8.0 (strony Razpr, MVC)
- Przeglądarki internetowe
-
- Krawędź 119
Środowisko pracy
- Visual Studio (jeśli dołączasz również programy serwerowe)
-
- informacji o wersji Visual Studio 2022
- ASP.NET Core (jeśli zawiera również programy serwerowe)
-
- 8.0 (strony Razpr, MVC)
- Przeglądarki internetowe
-
- Brzeg
- Google Chrome
- Inne przeglądarki (nie wszystkie zaznaczone)
(* Główną częścią tej porady jest proces po stronie klienta, więc strona serwera może być dowolna)
Na początku
Głównym celem tych wskazówek jest program kliencki (Javascript), a program serwerowy służy tylko do pobierania plików. Dlatego nie ma znaczenia, jaki jest program serwera, o ile może zmusić Cię do pobrania pliku.
Poproś użytkowników o pobieranie plików, gdy są one dostępne na serwerze
Pan/Pani umożliwia pobieranie plików po otrzymaniu prośby. W tym czasie celowo czekamy na serwerze przez określony czas, aby łatwo było zrozumieć początek i koniec pobierania.
Oto, co dzieje się po stronie serwera Razor Pages i MVC: Można go zaimplementować w innych projektach, takich jak internetowy interfejs API.
Strony brzytwy : Strony/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");
}
}
}
Przetwarzanie klientów
Zwykle pobierasz plik, uzyskując dostęp do określonego adresu URL w przeglądarce internetowej. Jeśli chcesz coś zrobić po zakończeniu pobierania, możesz uruchomić pobieranie za pomocą JavaScript.
Można to zrobić na wiele sposobów, ale w tym przypadku użyjemy , który jest również XMLHttpRequest
źródłem przetwarzania asynchronicznego.
Możesz także użyć funkcji ajax jQuery lub interfejsu API pobierania.
a
href
Adres URL pobierania jest zapisywany w tagu, a id
proces jest wykonywany po kliknięciu ustawionego nadownload
.
$('#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
Zwykle, jeśli pozostawisz kliknięty element, domyślny proces pobierania zostanie przeniesiony, więc e.preventDefault();
wywołujemy, aby wyłączyć domyślny proces.
href
Pobierz adres URL pobierania z i XMLHttpRequest
GET
ustaw go tak, aby pobierał go z .
XMLHttpRequest.responseType
blob
, aby poinstruować dane binarne, które mają zostać pobrane.
XMLHttpRequest.onload
Ponieważ proces po zakończeniu pobierania danych można opisać w zdarzeniu, proces po zakończeniu pobierania jest zapisany tutaj.
Ponieważ dane zostały pobrane tylko do klienta, plik nie jest w rzeczywistości przechowywany lokalnie.
Aby zapisać plik lokalnie, możesz dodać znacznik zawierający pseudodane i sprawić, by a
zachowywał się tak, jakbyś kliknął łącze i zapisał plik.
Dane w tym czasie mogą window.URL.createObjectURL
zostać przekonwertowane na adres URL przez funkcję, dzięki czemu href
można ją ustawić i sprawić, by działała.
Nazwę pliku, który ma zostać zapisany, można pobrać z nagłówka odpowiedzi, jeśli jest ona zawarta w odpowiedzi z serwera Content-Disposition
.
Ponieważ jest to trochę skomplikowane do zdobycia, myślę, że kod powinien być używany tak, jak jest.
Jeśli nazwa pliku nie jest podana na serwerze, nic na to nie poradzisz, więc myślę, że zostanie ustawiona na domyślną nazwę pliku lub nazwę pliku na końcu ścieżki URL.
Ponieważ tym razem wyświetlam go dopiero w konsoli po zapisaniu pliku, myślę, że żądaną operację można wykonać, przepisując tę część dowolnym kodem.
Po opisaniu procesu pobierania danych ostatnią rzeczą, jaką chcemy zrobić, jest XMLHttpRequest.send
wywołanie funkcji, aby faktycznie uruchomić żądanie.
Link do pobrania
Mr./Ms. Code podaje linki do wzorca pobierania pliku bezpośrednio oraz wzorca pobierania go za pomocą Javascript.
a
Możesz wpisać adres URL bezpośrednio w tagu href
, ale jeśli napiszesz następujące polecenie w ASP.NET Core, adres URL zostanie automatycznie href
rozwinięty do .
Razor Strony: 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: Views/Home/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>