Descargar texto mecanografiado y ASP.NET Core carga de archivos de procesamiento y protegido

directorio

introducción

fondo

Utilizando el código

Registre su API

main.ts

API-plugin.d.ts

carga de archivos

sumisión

métodos de servicio API

método API ASP.NET Core

Descargar archivo

API de cliente de descarga

La protección de los archivos cargados


introducción

Yo estaba trabajando recientemente en un sitio web que necesita para cargar y descargar archivos. Parece que para algunas personas, es un lugar de tormento, así que pensé que debería escribir un pequeño artículo ( desde mi último artículo ha sido demasiado tiempo, ha caducado desde hace mucho tiempo ) , tanto para mi propia descendencia, también para otras cosas.

fondo

Estoy construyendo una aplicación que almacena las ventas de productos digitales. Todo front-end con VueJS escritos con un ASP.NET Core backend API , para proporcionar archivos y SPA .

Utilizando el código

El código es fácil de explicar, por lo que sólo se describe brevemente la función de cada módulo, en lugar de la descripción detallada de todos los contenidos y estropear el tema.

Registre su API

main.ts

Importe su api módulo

import api from './services/api'; -- this is my sites api
...
Vue.prototype.$api = api;

API-plugin.d.ts

Los api $ las variables asociadas a la Vue y asignar Api tipo.

import { Api } from './services/api';
 
 declare module 'vue/types/vue' {
     interface Vue {
         $api: Api;
     }
}

export default Api;

carga de archivos

En mis VueJS Asamblea, datos () crea un objeto interno variable que se utiliza para guardar el archivo para ser enviados al servidor.

files: new FormData(),

Añadí que el usuario responda a un método de control para agregar archivos para subir archivos

handleFileUpload(fileList: any) {
    this.files.append('file', fileList[0], fileList[0].name);
},

Vue plantilla componente contiene el elemento de entrada de archivo

<input type="file" v-on:change="handleFileUpload($event.target.files)" />

sumisión

Entonces, cuando un usuario de la interfaz de usuario cuando se realizan operaciones de carga provocada, voy a llamar a mi API .

this.$api.uploadFile(this.files)
    .then((response: <<YourResponseType>>) => {
        this.hasError = false;
        this.message = 'File uploaded';
    }).catch((error) => {
        this.hasError = true;
        this.message = 'Error uploading file';
    });

API métodos de servicio

En lo anterior golondrina método de montaje que aparece en mi API llama a este método en el servicio.

public async uploadFile(fileData: FormData): Promise<<<YourResponseType>>> {
    return await axios.post('/api/to/your/upload/handler', fileData, { headers: { 'Content-Type': 'multipart/form-data' } })
        .then((response: any) => {
            return response.data;
        })
        .catch((error: any) => {
            throw new Error(error);
        });
}

API ASP.NET Core método

El código en el método de acuerdo con sus propios requisitos son muy diferentes, pero la estructura básica se parece a esto.

[HttpPost("/api/to/your/upload/handler")]
[Consumes("multipart/form-data")]
public async Task<IActionResult> UploadHandler(IFormCollection uploads)
{
    if (uploads.Files.Length <= 0) { return BadRequest("No file data"); }

    foreach (var f in uploads.Files) 
    {
        var filePath = "YourGeneratedUniqueFilePath";
        using (var stream = System.IO.File.Create(filePath))
        {
            await file.CopyToAsync(stream);
        }
    }

    return Ok();
}

Descargar archivo

El inicio del lado del servidor, su API están disponibles varios métodos a continuación. Desde que uso Kestral desde, he elegido para utilizar el ControllerBase.PhysicalFile () método, pero si el controlador es más adecuado para sus necesidades, entonces el controlador así como el método controlador básico que los retornos ControllerBase.File () .

Desde que cargar y almacenar mis datos asociados a una entidad, que sea requerido por la ID valor solicitud de descarga, pero se puede utilizar cualquier método que se adapte a sus necesidades.

[HttpGet("[action]")]
public async Task<IActionResult> GetFile(string id)
{
    var dir = "GetOrBuildYourDirectoryString";
    var fileName = "GetYourFileName";

    var mimeType = GetMimeType(fileName);

    var path = Path.Combine(dir, fileName);

    return PhysicalFile(path, mimeType, version.FileName);
}

public string GetMimeType(string fileName)
{
    var provider = new FileExtensionContentTypeProvider();
    string contentType;
    if (!provider.TryGetContentType(fileName, out contentType))
    {
        contentType = "application/octet-stream";
    }

    return contentType;
}

Nota: FileExtensionContentTypeProvider tipos de Microsoft.AspNetCore.StaticFiles NuGet paquete

Install-Package Microsoft.AspNetCore.StaticFiles -Version 2.2.0

El cliente de API de descarga

Para llamar a esto en el servidor GetFile () método, nuestros clientes API necesidades de servicio para el método de descarga pública. Esto haría que las cosas se complican un poco. Puede que tenga que configurar el servidor para proporcionar y / o divulgación de encabezado de disposición. Esto es un poco más allá del alcance de este artículo, porque quiero que sea sencillo.

No necesitará realizar todos los pasos necesarios para acceder a esta cabecera, pero sí tiene que realizar alguna operación para extraer los datos de los clientes requeridos - sobre todo el nombre del archivo. Por desgracia, este código no es especialmente buena. Si alguien tiene alguna sugerencia sobre cómo mejorar, por favor hágamelo saber.

public async downloadFile(id: string): Promise<void> {
    return await axios.get('/api/download/getfile?id=' + id, { responseType : 'blob' } )
        .then((response: any) => {
            const disposition = response.headers['content-disposition'];
            let fileName = '';

            if (disposition && disposition.indexOf('attachment') !== -1) {
                const filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
                const matches = filenameRegex.exec(disposition);
                if (matches != null && matches[1]) {
                    fileName = matches[1].replace(/['"]/g, '');
                }
            }

            const fileUrl = window.URL.createObjectURL(new Blob([response.data]));
            const fileLink = document.createElement('a');
            fileLink.href = fileUrl;
            fileLink.setAttribute('download', fileName);
            document.body.appendChild(fileLink);
            fileLink.click();
        })
        .catch((error: any) => {
            throw new Error(error);
        });
}

Esto establecerá el cliente para descargar y abrir el archivo de usuario local Guardar navegador convencional de diálogo.

La protección de los archivos cargados

En vista de que el código anterior es " Manual " proceso de descarga y carga de archivos, se puede considerar, navegador HTML simple de archivos en la URL no es una situación ideal. En mi ejemplo, he subido archivos a procesar en el directorio de descargas.

Con el fin de proteger esta " descargas " de directorio, yo estaba en el StartUp.cs Configurar una pequeña cantidad de la lógica se asigna al método de .NET Core  IApplicationBuilder ejemplo. Se interceptará esta URL cualquier solicitud y envía un 401 respuesta.

app.Map("/downloads", subApp => {
    subApp.Use(async (context, next) =>
    {
        context.Response.StatusCode = StatusCodes.Status401Unauthorized;
    });
});

Cualquier intento de acceder a las descargas se guiará persona presenta en el directorio, el navegador recibirá una respuesta de error del servidor.

Espero que puedan encontrar una descripción breve de alguna utilidad en este método.

Publicado 71 artículos originales · ganado elogios 152 · vistas 520 000 +

Supongo que te gusta

Origin blog.csdn.net/mzl87/article/details/105082237
Recomendado
Clasificación