使用`OneUpUploaderBundle`和`UPPY`在`Symfony v6.3`中上传文件后向用户显示服务器错误消息

2fjabf4q  于 2023-10-24  发布在  其他
关注(0)|答案(1)|浏览(151)

简介

我正在使用:

  • Symfony v6.3.3
  • OneUpUploaderBundle v4.0.1
  • UPPY(通过Yarn)
  • "@uppy/core": "^3.3.1"
  • "@uppy/dashboard": "^3.4.2"
  • "@uppy/golden-retriever": "^3.1.0"
  • "@uppy/locales": "^3.2.3"
  • "@uppy/xhr-upload": "^3.3.1"

在撰写本文时,还没有正式的OneUpUploaderBundleUPPY集成。幸运的是,OneUpUploaderBundle的开发人员具有前瞻性思维,并添加了support for a custom Uploader
所以我选择实施它。

实现

首先,我选择使用Blueimp jQuery File Uploader设置上传,因为它是由bundle支持的。
成功后,我转移到设置上传与UPPYCustom uploader
对于我的CustomUploader,我选择了BlueimpController-从一堆其他上传器的捆绑支持。
目前上传工程与自定义上传(为UPPY)。

问题

出于安全原因,我不允许上传extension * 与其mime type不对应 * 的文件。我用UploadValidationListener中的Symfony检查此(在服务器上,收到文件后)。在这种情况下,我需要向用户显示错误,但不知道如何将其传递给UPPY Dashboard
现状是:文件上传成功,但这样的文件不会被保留-因为它没有通过验证。如果没有消息,用户会想知道:幻影文件在哪里,因为他们看到他们上传成功!

代码

下面是UPPY设置方式

'use strict';

import Translator from 'bazinga-translator';
import Uppy from '@uppy/core';
import Dashboard from '@uppy/dashboard';
import GoldenRetriever from '@uppy/golden-retriever';
import XHR from '@uppy/xhr-upload';

import '@uppy/core/dist/style.css';
import '@uppy/dashboard/dist/style.css';
import en_US from "@uppy/locales/lib/en_US";

const js_data = document.querySelector('#js-data');
let data_allowed_file_types_str = js_data.dataset.allowedFileTypes;
const data_allowed_file_types = data_allowed_file_types_str.split('|');
const data_allowed_file_size_min = js_data.dataset.allowedFileSizeMin;
const data_allowed_file_size_max = js_data.dataset.allowedFileSizeMax;
const data_upload_endpoint = js_data.dataset.uploadEndpoint;

const uppy = new Uppy({
    debug: false,
    locale: en_US,
    onBeforeFileAdded: (currentFile, files) =>
    {
        const do_not_allow_arr = ['do_not_allow_me_1.txt', 'do_not_allow_me_2.txt', 'do_not_allow_me_3.txt'];
        let allowed = true;
        do_not_allow_arr.forEach((element) =>
        {
            if (currentFile.name === element)
            {
                allowed = false;
                uppy.log(Translator.trans('upload.error.skipFilesFromBlockList'));
                uppy.info((Translator.trans('upload.error.skipFilesFromBlockList')), 'error', 5000);
                return allowed;
            }
        });
        return allowed;
    },
});

uppy.use(GoldenRetriever);

uppy.use(Dashboard, {
        inline: true,
        target: '#uppy-dashboard',
        id: 'uppy',
        width: '100%',
        proudlyDisplayPoweredByUppy: false,
        showProgressDetails: true,
    });

uppy.use(XHR, {
        endpoint: data_upload_endpoint
    });

uppy.setOptions({
    restrictions:
        {
            minNumberOfFiles: 1,
            maxNumberOfFiles: 1,
            minFileSize: data_allowed_file_size_min,
            minTotalFileSize: data_allowed_file_size_min,
            maxTotalFileSize: data_allowed_file_size_max,
            allowedFileTypes: data_allowed_file_types
        },
        //autoProceed: true
    });

uppy.on('file-added', (file) => {
    console.log('Added file', file);
});

uppy.on('upload-success', (file, responseObject) => {
    // (depending on the uploader plugin used, it might contain
    // less info, the example is for @uppy/xhr-upload)
    // responseObject = {
    //     status, // HTTP status code (0, 200, 300)
    //     body, // response body
    //     uploadURL // the file url, if it was returned
    // }
    console.log('after upload success');
});

uppy.on('upload-error', (file, responseObject) => {
    // responseObject = {
    //     status, // HTTP status code (0, 200, 300)
    //     body // response body
    // }
    console.log('after upload error');
});

下面是验证器代码

<?php

namespace App\EventListener;

use App\Entity\FileType;
use App\UltraHelpers\UltraHelpers;
use Doctrine\Persistence\ManagerRegistry;
use Oneup\UploaderBundle\Event\ValidationEvent;
use Oneup\UploaderBundle\Uploader\Exception\ValidationException;
use Symfony\Component\Mime\MimeTypes;

class UploadValidationListener
{
    /**
     * @var ManagerRegistry
     */
    private ManagerRegistry $doctrine;

    /**
     * @var UltraHelpers
     */
    private UltraHelpers $ultraHelpers;

    public function __construct(
        ManagerRegistry $doctrine,
        UltraHelpers $ultraHelpers
    )
    {
        $this->doctrine = $doctrine;
        $this->ultraHelpers = $ultraHelpers;
    }

    public function onValidate(ValidationEvent $event): void
    {
        $repo_file_Type = $this->doctrine->getRepository(FileType::class);
        $file_extensions_allowed = $repo_file_Type->getActivatedFileTypeOnlyListArray();

        $mimeTypes = new MimeTypes();

        $errors = [];

        $file_list_banned = [];
        $file_list_banned[] = 'do_not_allow_me_1.txt';
        $file_list_banned[] = 'do_not_allow_me_2.txt';
        $file_list_banned[] = 'do_not_allow_me_3.txt';

        $config = $event->getConfig();
        $file = $event->getFile();

        $filtered_file_info = $this->ultraHelpers->filterFileInfoFromFileName($file->getClientOriginalName());
        $transliterated_file_name = $filtered_file_info['name'];
        $full_file_name = $transliterated_file_name .'.'. $filtered_file_info['extension'];

        $file_extension = $filtered_file_info['extension'];
        $file_mime_type_from_file = $mimeTypes->guessMimeType($file);
        $file_mime_types_from_extension = $mimeTypes->getMimeTypes($file_extension);

 
        // process forbidden_files
        if (in_array($full_file_name, $file_list_banned, true))
        {
            $errors[] = 'error.file_banned';
        }

        // If mime type of current file does not correspond to extensions mime type
        // Damaged file or specially prepared for research / hacking
        if (!in_array($file_mime_type_from_file, $file_mime_types_from_extension, true))
        {
            $errors[] = 'error.mime_type_mismatch';
        }

        if (!empty($errors))
        {
            throw new ValidationException(implode(', ', $errors));
        }
    }
}
biswetbf

biswetbf1#

可以使用ExceptionListener,请在这里查看示例https://symfony.com/doc/current/event_dispatcher.html#creating-an-event-listener
services.yaml

services:
    App\Listener\ExceptionListener:
        tags:
            - { name: kernel.event_listener, event: kernel.exception }

相关问题