Хобрук: Ваш путь к мастерству в программировании

Загрузить файл из html ‹input› на фляжный сервер с помощью js

Я пытаюсь отправить файл из интерфейса JS в серверную часть Flask. Но мой сервер фляги, похоже, не получает файл. Он работает при переходе на HTML-страницу бэкэнда фляги и отправке вручную, но я хочу, чтобы внешний интерфейс отправлял файл на серверную часть.

Вот рассматриваемый javascript:

function send() {
    const formData = new FormData();
    const files = document.getElementById("file");
    formData.append("file", files.files[0]);
    const requestOptions = {
        headers: {
            "Content-Type": "multipart/form-data",
        },
        mode: "no-cors",
        method: "POST",
        files: files.files[0],
        body: formData,
    };
    console.log(requestOptions);

    fetch("http://localhost:5000/upload", requestOptions).then(
        (response) => {
            console.log(response.data);
        }
    );
}

export default function App() {
    return (
        <div className="App" id="App">
            <header className="App-header">
                <Button variant="outlined" component="label" size="large">
                    Load Audio
                    <input
                        id="file"
                        type="file"
                        onChange={send}
                        hidden
                    />
                </Button>
            </header>
        </div>
    );
}

Вот скрипт flask python для обработки входящих запросов:

@app.route("/upload", methods=["GET", "POST"])
def upload():
    if request.method == 'POST':
        if 'file' not in request.files:
            print(1)
            flash('No file part')
            return redirect(request.url)
        file = request.files['file']
        if file.filename == '':
            print(2)
            flash('No selected file')
            return redirect(request.url)
        if file and allowed_file(file.filename):
            print(3)
            filename = secure_filename(file.filename)
            session["id"] = filename
            file.save(os.path.join('UPLOAD', filename))
            return redirect(url_for('uploaded',
                                    filename=filename))

    return render_template('upload.html')

Он печатает 1, поэтому файл не найден.

Если это полезно, вот отладка с print(request.headers):

Host: localhost:5000
Connection: keep-alive
Content-Length: 412313
Sec-Ch-Ua: "Chromium";v="88", "Google Chrome";v="88", ";Not A Brand";v="99"
Sec-Ch-Ua-Mobile: ?0
Content-Type: multipart/form-data
Accept: */*
Origin: http://localhost:3000
Sec-Fetch-Site: same-site
Sec-Fetch-Mode: no-cors
Sec-Fetch-Dest: empty
Referer: http://localhost:3000/
Accept-Encoding: gzip, deflate, br

Я много читал в Интернете о том, как загрузить файл в этой ситуации, но я не могу заставить его работать. Было бы здорово получить помощь!


Ответы:


1

Ваша обработка файлов в Flask кажется правильной. Однако способ, которым вы указываете свой заголовок Content-Type, кажется непонятным для Flask.

Запустив упрощенный пример вашего кода, я попытался протестировать его с помощью cURL следующим образом:

curl -XPOST http://localhost:5000/upload -F [email protected]

Таким образом, Flask понял, что файл был загружен, и я смог увидеть его в request.files:

ipdb> request.files
ImmutableMultiDict([('file', <FileStorage: 'TestFile.txt' ('text/plain')>)])

Мое внимание также привлекло то, что Content-Type имеет указанную границу:

('Content-Type', 'multipart/form-data; boundary=------------------------aa8098f7b7fa6c61')

Это заставляет меня предположить, что указание Content-Type: multipart/form-data вручную не работает.

Поскольку вы пытаетесь выполнить загрузку через JS fetch, рассмотрите возможность поиска здесь. Они также не рекомендуют устанавливать заголовок вручную.

10.03.2021
  • Библиотека выборки должна делать это автоматически, когда вы отправляете данные формы. 11.03.2021
  • Новые материалы

    LeetCode Проблема 41. Первый пропущенный положительный результат
    LeetCode Проблема 41. Первый пропущенный положительный результат Учитывая несортированный массив целых чисел, найдите наименьшее пропущенное положительное целое число. Пример 1: Input:..

    Расистский и сексистский робот, обученный в Интернете
    Его ИИ основан на предвзятых данных, которые создают предрассудки. Он словно переходит из одного эпизода в другой из серии Черное зеркало , а вместо этого представляет собой хронику..

    Управление состоянием в микрофронтендах
    Стратегии бесперебойного сотрудничества Микро-фронтенды — это быстро растущая тенденция в сфере фронтенда, гарантирующая, что удовольствие не ограничивается исключительно бэкэнд-системами..

    Декларативное и функциональное программирование в стиле LINQ с использованием JavaScript с использованием каррирования и генератора ...
    LINQ - одна из лучших функций C #, которая обеспечивает элегантный способ написания кода декларативного и функционального стиля, который легко читать и понимать. Благодаря таким функциям ES6,..

    Структуры данных в C ++ - Часть 1
    Реализация общих структур данных в C ++ C ++ - это расширение языка программирования C, которое поддерживает создание классов, поэтому оно известно как C с классами . Он используется для..

    Как я опубликовал свое первое приложение в App Store в 13 лет
    Как все началось Все началось три года назад летом после моего четвертого класса в начальной школе. Для меня, четвертого класса, лето кажется бесконечным, пока оно не закончится, и мой отец..

    Что в лицо
    Очерк о возвращении физиогномики и о том, почему мы должны это приветствовать. История начинается со странной науки. Р. Тора Бьорнсдоттир, Николас О. Рул. Видимость социального класса по..