Javascript para realizar el procesamiento después de descargar un archivo
Entorno de verificación de la operación
- Visual Studio
-
- Visual Studio 2022
- ASP.NET Núcleo
-
- 8.0 (Páginas Razpr, MVC)
- Navegadores web
-
- Borde 119
Entorno operativo
- Visual Studio (si también incluye programas de servidor)
-
- Visual Studio 2022
- ASP.NET Core (si también incluye programas de servidor)
-
- 8.0 (Páginas Razpr, MVC)
- Navegadores web
-
- Borde
- Google Chrome
- Otros navegadores (no todos marcados)
(* El cuerpo principal de esta sugerencia es el proceso del lado del cliente, por lo que el lado del servidor puede ser cualquier cosa)
Al principio
El enfoque principal de estos consejos es el programa cliente (Javascript), y el programa servidor solo está ahí para descargar archivos. Por lo tanto, no importa cuál sea el programa del servidor, siempre y cuando pueda hacer que descargues el archivo.
Hacer que los usuarios descarguen archivos cuando se accede a ellos en el servidor
Sr./Sra. le permite descargar archivos cuando recibe una solicitud. En ese momento, esperamos deliberadamente una cierta cantidad de tiempo en el servidor para que sea fácil entender el inicio y el final de la descarga.
Esto es lo que sucede en el lado del servidor de Razor Pages y MVC: Puede implementarlo en otros proyectos, como Web API.
Razor Pages : 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");
}
}
}
Procesamiento de clientes
Normalmente, se descarga un archivo accediendo a una URL especificada en un navegador web. Si desea hacer algo después de que se complete la descarga, puede ejecutar la descarga con Javascript.
Hay muchas formas de hacer esto, pero en este caso, usaremos , que también XMLHttpRequest
es el origen del procesamiento asíncrono.
También puede utilizar las funciones ajax de jQuery o la API Fetch.
a
href
La URL de descarga se escribe en la etiqueta y id
el proceso se ejecuta cuando se hace clic en la establecida endownload
.
$('#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, si dejas el elemento pulsado, el proceso de descarga por defecto se moverá, por lo que e.preventDefault();
llamamos a desactivar el proceso por defecto.
href
Obtenga la URL de descarga y XMLHttpRequest
GET
configúrela para obtenerla de .
XMLHttpRequest.responseType
blob
para indicar los datos binarios que se van a descargar.
XMLHttpRequest.onload
Dado que el proceso después de que se complete la descarga de datos se puede describir en el evento, el proceso después de que se complete la descarga se escribe aquí.
Dado que los datos solo se han descargado en el cliente, el archivo no se almacena localmente.
Para guardar un archivo localmente, puede agregar una etiqueta que contenga pseudodatos y hacer que a
se comporte como si hubiera hecho clic en un enlace y hubiera guardado el archivo.
La función puede window.URL.createObjectURL
convertir los datos en ese momento en una URL, por lo href
que puede configurarlos y hacer que funcionen.
El nombre del archivo que se va a guardar se puede recuperar del encabezado de respuesta si está incluido en la respuesta del Content-Disposition
servidor.
Dado que es un poco complicado de adquirir, creo que el código debería usarse tal cual.
Si el nombre del archivo no se especifica en el servidor, no se puede ayudar, por lo que creo que se establecerá en el nombre de archivo predeterminado o el nombre de archivo al final de la ruta de la URL.
Dado que esta vez solo lo muestro en la consola después de guardar el archivo, creo que la operación deseada se puede ejecutar reescribiendo esta parte con código arbitrario.
Una vez que se describe el proceso de descarga de datos, lo último que queremos hacer es XMLHttpRequest.send
llamar a una función para iniciar la solicitud.
Enlace de ejecución de descarga
Mr./Ms. Code proporciona enlaces al patrón de descarga del archivo directamente y al patrón de descarga con Javascript.
a
Puede escribir la URL directamente en la href
etiqueta, pero si escribe lo siguiente en ASP.NET Core, la URL se expandirá automáticamente href
a .
Razor Pages : 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>