Javascript för att utföra bearbetning efter nedladdning av en fil
Miljö för verifiering av åtgärder
- Visuell studio
-
- Visual Studio 2022
- ASP.NET kärna
-
- 8.0 (Razpr-sidor, MVC)
- Webbläsare
-
- Kant 119
Omvärld
- Visual Studio (om du även inkluderar serverprogram)
-
- Visual Studio 2022
- ASP.NET Core (om den även innehåller serverprogram)
-
- 8.0 (Razpr-sidor, MVC)
- Webbläsare
-
- Kant
- Google Chrome
- Andra webbläsare (inte alla kontrollerade)
(* Huvuddelen av detta tips är processen på klientsidan, så serversidan kan vara vad som helst)
Först
Huvudfokus för dessa tips är klientprogrammet (Javascript), och serverprogrammet är bara till för att ladda ner filer. Därför spelar det ingen roll vad serverprogrammet är, så länge det kan få dig att ladda ner filen.
Låt användarna ladda ned filer när de används på servern
Mr./Ms. låter dig ladda ner filer när du får en begäran. Vid den tiden väntar vi medvetet en viss tid på servern så att det är lätt att förstå början och slutet av nedladdningen.
Här är vad som händer på serversidan av Razor Pages och MVC: Du kan implementera den i andra projekt, till exempel webb-API.
Razor Sidor : Sidor/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");
}
}
}
Bearbetning av klienter
Normalt laddar du ned en fil genom att komma åt en angiven URL i en webbläsare. Om du vill göra något efter att nedladdningen är klar kan du köra nedladdningen med Javascript.
Det finns många sätt att göra detta, men i det här fallet kommer vi att använda , som också XMLHttpRequest
är ursprunget till asynkron bearbetning.
Du kan också använda jQuery ajax-funktioner eller Fetch API.
a
href
Nedladdnings-URL:en skrivs i taggen och id
processen utförs när du klickar på den som är inställd pådownload
.
$('#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
Normalt, om du lämnar elementet klickat, kommer standardnedladdningsprocessen att flyttas, så e.preventDefault();
vi ringer för att inaktivera standardprocessen.
href
Hämta nedladdnings-URL:en från och XMLHttpRequest
GET
ställ in den för att hämta den från .
XMLHttpRequest.responseType
blob
för att instruera binära data som ska laddas ner.
XMLHttpRequest.onload
Eftersom processen efter att datanedladdningen har slutförts kan beskrivas i händelsen, skrivs processen efter att nedladdningen är klar här.
Eftersom data bara har laddats ner till klienten lagras filen inte lokalt.
Om du vill spara en fil lokalt kan du lägga till en tagg som a
innehåller pseudodata och få den att bete sig som om du hade klickat på en länk och sparat filen.
Data vid den tidpunkten kan window.URL.createObjectURL
konverteras till en URL av funktionen, så href
att du kan ställa in den på och få den att fungera.
Filnamnet som ska sparas kan hämtas från svarshuvudet om det ingår i svaret från Content-Disposition
servern.
Eftersom det är lite komplicerat att skaffa tycker jag att koden ska användas som den är.
Om filnamnet inte anges på servern kan det inte hjälpas, så jag tror att det kommer att ställas in på standardfilnamnet eller filnamnet i slutet av URL-sökvägen.
Eftersom jag den här gången bara visar den i konsolen efter att ha sparat filen, tror jag att den önskade operationen kan utföras genom att skriva om den här delen med godtycklig kod.
När datanedladdningsprocessen har beskrivits är det sista vi vill göra att XMLHttpRequest.send
anropa en funktion för att faktiskt starta begäran.
Ladda ner körningslänk
Mr./Ms. Code ger länkar till mönstret för att ladda ner filen direkt och mönstret för att ladda ner den med Javascript.
a
Du kan skriva URL:en direkt i taggen href
, men om du skriver följande i ASP.NET Core expanderas URL:en automatiskt href
till .
Razor Sidor: Sidor/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: Vyer/Hem/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>