Нужна помощь в понимании загрузки файлов в Python Flask, без / с Javascript + Ajax
Я пишу веб-приложение, которое позволяет пользователю загружать фотографии, а затем возвращает данные об этих фотографиях во внешний интерфейс, чтобы вызвать некоторую активность.
Я начал это, используя учебник / руководство, которое я нашел в Интернете, здесь
Однако я был очень удивлен, обнаружив, что это работает без JavaScript. Я не понимаю, как нажатие кнопки отправляет запрос о появлении всплывающего окна с просьбой выбрать файл. Откуда он знает, что кнопка предназначена для загрузки файлов? Нет, где в HTML я даю ему очевидный атрибут, который говорит ему загружать файл, и нигде в python/Flask я не выбираю кнопку, используемую для загрузки.
К моему удивлению, я также заметил, что в приведенном примере маршрут ДОЛЖЕН называться "/upload" для работы. Опять же, я не вижу, где что-то из этого определено или где я могу это изменить. Единственными файлами, которые используются для демонстрации по этой ссылке (которая является основой моего веб-приложения), являются app.py и index.html (файл setup.py, по-видимому, не нужен для запуска веб-сервера)
По мере развития моего веб-приложения я пытался добавить файл javascript, который получал бы ответ от маршрута / uploads и отображал его в интерфейсе, но вскоре столкнулся с проблемами. Кажется, я могу запускать / выгружать только из той загадочной силы, которая сейчас его запускает. Мой javascript не может получить к нему доступ, и поэтому у меня нет возможности получить ответ в JS, чтобы я мог отобразить его на внешнем интерфейсе так, как я хочу.
Может кто-нибудь помочь мне понять, как работает сервер загрузки файлов по ссылке, чтобы я мог изменить его для работы со своим JavaScript?
Пожалуйста, обратите внимание, что мое веб-приложение - это просто программа по этой ссылке с кучей анализа проделанных файлов. Единственное изменение, которое я сделал с точки зрения работы веб-приложения, заключается в том, что вместо перенаправления вас в загруженный файл оно должно возвращать строку с информацией об этом файле.
Я не чувствую, что стоит публиковать слишком много моего кода на python и HTML, так как все важные вещи есть в этой ссылке, но файл javascript приведен ниже.
"use strict";
var main = function() {
console.log("i am functioning!")
var show_similar_img = function(){
//Read megastatus
$.ajax({
method: "GET",
url: "/upload",
// contentType: 'application/json',
dataType: "string"
})
.done(function(media_info){
console.log(media_info)
});
}
$("#upload-btn").on("click",function(){
console.log("button pressed!")
show_similar_img()
})
}
console.log("i am being run!")
$(document).ready(main);
1 ответ
<input>
элемента type
атрибут file
Это то, как браузер знает, как обращаться с ним особым образом - как вы заметили, открывая всплывающее модальное окно, которое предлагает пользователю выбрать файл.
Маршрут должен называться " загрузить", потому что <form>
элемента action
Значение атрибута также называется загрузкой. Вы можете изменить название маршрута, если вы также изменили действие формы.
Фактически вы можете получить доступ к информации о файле (для файла, связанного с элементом ввода), используя JavaScript благодаря File API. В Mozilla Developer Network есть отличное руководство: https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications
Что касается вашей фактической реализации: во-первых, вы также захотите запретить обработку отправки формы "обычным" (синхронным) способом, поэтому вам нужно вызвать preventDefault
на мероприятии:
$("#upload-btn").on("click",function(event) {
event.preventDefault();
console.log("button pressed!")
show_similar_img()
})
Во-вторых, я предполагаю, что вы действительно хотите отправить файл на сервер (запущенный на Python/Flask), поэтому вы хотите, чтобы ваш AJAX-запрос был POST, а не GET. Поэтому вам нужно изменить show_similar_img
, чтобы отправить запрос как POST, а также включить файл в данные запроса, используя вышеупомянутый File API. Что-то вроде этого:
var show_similar_img = function(){
var formData = new FormData();
var file = $("input[type='file']")[0].files[0];
formData.append("file", file);
$.ajax({
url : "/upload",
type : "POST",
data : formData,
contentType: false,
processData: false
})
.done(function(media_info){
console.log(media_info)
});
}
Редактировать - я должен добавить, что я не очень знаком с Flask или тонкостями его request
объект. Я предполагаю, что независимо от того, загружен ли файл как часть отправки формы или асинхронного запроса, он все равно будет доступен на request.files['file']
, но возможно, что Flask не делает асинхронно загруженные файлы доступными в request.files
толковый словарь. Я очень уверен, однако, что файл будет доступен где-то на request
объект, поэтому вам может понадобиться обратиться к документации Flask. Вы также можете использовать pdb
добавить точку останова в коде на стороне сервера и проверить request
объект, чтобы увидеть, что он держит (и где он его держит).