Javascript om verwerking uit te voeren na het downloaden van een bestand
Omgeving voor bedrijfsverificatie
- Visual Studio
-
- Visual Studio 2022
- ASP.NET kern
-
- 8.0 (Razpr-pagina's, MVC)
- Webbrowsers
-
- Rand 119
Werkomgeving
- Visual Studio (als u ook serverprogramma's meetelt)
-
- Visual Studio 2022
- ASP.NET Core (als het ook serverprogramma's bevat)
-
- 8.0 (Razpr-pagina's, MVC)
- Webbrowsers
-
- Rand
- Google Chrome
- Andere browsers (niet allemaal aangevinkt)
(* Het belangrijkste deel van deze tip is het client-side proces, dus de serverkant kan van alles zijn)
Eerst
De belangrijkste focus van deze tips is het clientprogramma (Javascript) en het serverprogramma is er alleen om bestanden te downloaden. Daarom maakt het niet uit wat het serverprogramma is, zolang het u maar het bestand kan laten downloaden.
Laat gebruikers bestanden downloaden wanneer ze op de server worden geopend
Met Mr./Ms. kunt u bestanden downloaden wanneer u een verzoek ontvangt. Op dat moment wachten we bewust een bepaalde tijd op de server, zodat het begin en einde van de download gemakkelijk te begrijpen is.
Dit is wat er gebeurt aan de serverkant van Razor Pages en MVC: U kunt het implementeren in andere projecten, zoals Web API.
Razor Pagina's : Pagina's/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");
}
}
}
Verwerking van klanten
Normaal gesproken downloadt u een bestand door een opgegeven URL in een webbrowser te openen. Als u iets wilt doen nadat de download is voltooid, kunt u de download uitvoeren met Javascript.
Er zijn veel manieren om dit te doen, maar in dit geval zullen we gebruiken , wat ook XMLHttpRequest
de oorsprong is van asynchrone verwerking.
U kunt ook jQuery ajax-functies of de Fetch API gebruiken.
a
href
De download-URL wordt in de tag geschreven en id
het proces wordt uitgevoerd wanneer op de tag download
wordt geklikt.
$('#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
Normaal gesproken, als u het element ingedrukt laat, wordt het standaard downloadproces verplaatst, dus e.preventDefault();
we roepen op om het standaardproces uit te schakelen.
href
Haal de download-URL op van en XMLHttpRequest
GET
stel deze in om deze op te halen van .
XMLHttpRequest.responseType
blob
om de binaire gegevens te instrueren die moeten worden gedownload.
XMLHttpRequest.onload
Aangezien het proces nadat het downloaden van de gegevens is voltooid, kan worden beschreven in het evenement, wordt het proces nadat het downloaden is voltooid hier beschreven.
Omdat de gegevens alleen naar de client zijn gedownload, wordt het bestand niet daadwerkelijk lokaal opgeslagen.
Om een bestand lokaal op te slaan, kunt u een tag toevoegen die pseudogegevens bevat en ervoor zorgen dat a
het zich gedraagt alsof u op een link hebt geklikt en het bestand hebt opgeslagen.
De gegevens op dat moment kunnen window.URL.createObjectURL
door de functie worden omgezet in een URL, zodat href
u deze kunt instellen en laten werken.
De bestandsnaam die moet worden opgeslagen, kan worden opgehaald uit de antwoordheader als deze is opgenomen in het antwoord van de Content-Disposition
server.
Omdat het een beetje ingewikkeld is om te verkrijgen, denk ik dat de code moet worden gebruikt zoals hij is.
Als de bestandsnaam niet op de server is opgegeven, kan er niets aan worden gedaan, dus ik denk dat deze wordt ingesteld op de standaard bestandsnaam of de bestandsnaam aan het einde van het URL-pad.
Aangezien ik het deze keer pas in de console weer geef nadat ik het bestand heb opgeslagen, denk ik dat de gewenste bewerking kan worden uitgevoerd door dit deel te herschrijven met willekeurige code.
Zodra het proces voor het downloaden van gegevens is beschreven, is XMLHttpRequest.send
het laatste wat we willen doen een functie aanroepen om het verzoek daadwerkelijk te starten.
Hardlooplink downloaden
Mr./Ms. Code biedt links naar het patroon van het rechtstreeks downloaden van het bestand en het patroon van het downloaden met Javascript.
a
U kunt de URL rechtstreeks in de href
tag schrijven, maar als u het volgende in ASP.NET Core schrijft, wordt de URL automatisch href
uitgevouwen tot .
Razor Pagina's : Pagina's/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 : Weergaven/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>