Javascript para executar o processamento após o download de um arquivo
Ambiente de verificação de operação
- Estúdio Visual
-
- Visual Studio 2022
- ASP.NET Núcleo
-
- 8.0 (Páginas Razpr, MVC)
- Navegadores da Web
-
- Borda 119
Ambiente operacional
- Visual Studio (se você também incluir programas de servidor)
-
- Visual Studio 2022
- ASP.NET Core (se também incluir programas de servidor)
-
- 8.0 (Páginas Razpr, MVC)
- Navegadores da Web
-
- Borda
- Google Chrome
- Outros navegadores (nem todos marcados)
(* O corpo principal desta dica é o processo do lado do cliente, então o lado do servidor pode ser qualquer coisa)
Inicialmente
O foco principal dessas dicas é o programa cliente (Javascript), e o programa servidor está lá apenas para baixar arquivos. Portanto, não importa qual é o programa do servidor, desde que ele possa fazer você baixar o arquivo.
Fazer com que os usuários baixem arquivos quando eles são acessados no servidor
Mr./Ms. permite que você baixe arquivos quando receber uma solicitação. Nesse momento, esperamos deliberadamente por um certo período de tempo no servidor para que seja fácil entender o início e o fim do download.
Aqui está o que acontece no lado do servidor do Razor Pages e do MVC: Você pode implementá-lo em outros projetos, como API Web.
Páginas Navalha : Páginas/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");
}
}
}
Processamento do cliente
Normalmente, você baixa um arquivo acessando uma URL especificada em um navegador da Web. Se você quiser fazer algo depois que o download for concluído, você pode executar o download com Javascript.
Existem muitas maneiras de fazer isso, mas neste caso, usaremos , que também XMLHttpRequest
é a origem do processamento assíncrono.
Você também pode usar funções jQuery ajax ou a API Fetch.
a
href
A URL de download é gravada na tag e id
o processo é executado quando o definido como download
é clicado.
$('#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
Normalmente, se você deixar o elemento clicado, o processo de download padrão será movido, então e.preventDefault();
chamamos para desabilitar o processo padrão.
href
Obtenha o URL de download de e XMLHttpRequest
GET
defina-o para obtê-lo de .
XMLHttpRequest.responseType
blob
para instruir os dados binários a serem baixados.
XMLHttpRequest.onload
Como o processo após a conclusão do download dos dados pode ser descrito no evento, o processo após a conclusão do download é escrito aqui.
Como os dados só foram baixados para o cliente, o arquivo não é realmente armazenado localmente.
Para salvar um arquivo localmente, você pode adicionar uma tag que a
contenha pseudodados e fazê-lo se comportar como se você tivesse clicado em um link e salvo o arquivo.
Os dados nesse momento podem window.URL.createObjectURL
ser convertidos em uma URL pela função, para href
que você possa configurá-los e fazê-los funcionar.
O nome do arquivo a ser salvo pode ser recuperado do cabeçalho da resposta se estiver incluído na resposta do Content-Disposition
servidor.
Como é um pouco complicado de adquirir, acho que o código deve ser usado como está.
Se o nome do arquivo não for especificado no servidor, ele não poderá ser ajudado, então acho que ele será definido como o nome de arquivo padrão ou o nome do arquivo no final do caminho da URL.
Como desta vez só o exibi no console depois de salvar o arquivo, acho que a operação desejada pode ser executada reescrevendo essa parte com código arbitrário.
Uma vez que o processo de download de dados é descrito, a última coisa que queremos fazer é XMLHttpRequest.send
chamar uma função para realmente iniciar a solicitação.
Baixar link de execução
Mr./Ms. Code fornece links para o padrão de download do arquivo diretamente e o padrão de baixá-lo com Javascript.
a
Você pode escrever a URL diretamente na href
tag , mas se escrever o seguinte no ASP.NET Core, a URL será expandida automaticamente href
para .
Páginas Razor : 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 : Visualizações/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>