Как заставить мой HTTP-запрос вести себя так же, как форма - PullRequest
2 голосов
/ 24 марта 2019

Мне нужна помощь с моим HTTP-запросом.Вот настройки:

  1. Веб-страница загружает изображение в форму и отправляет его на работающий флакон сервера Python (с формой или с пользовательским запросом http)
  2. Бутылка получает файл, дайте его в качестве входных данных для скрипта Python, получите результат и верните его на веб-страницу

На веб-сайте бутылки есть пример с формой: https://bottlepy.org/docs/dev/tutorial.html#file-uploads Я пробовали это работает.Вот код, который я использовал:

<html>
  <head>
  </head>   
  <body>
    <form action="http://localhost:8080/solve" method="POST" enctype="multipart/form-data" norm="form" id='myForm'>
      Select a file: <input type="file" name="upload"/>
      <input type="submit" value="Start upload" />
    </form>
  </body>     
</html>

В бутылке у меня есть:

@route('/solve', method='POST')
def solve():
    file     = request.files.get('upload')
    name, ext = os.path.splitext(file.filename)
    if ext not in ('.png','.jpg','.jpeg'):
        return 'File extension not allowed.'
    print(file.name)
    resolved = sudoku.solve(file.file)
    return str(resolved)

Это «работает», но форма перенаправляет меня на localhost: 8080, и это не то, что я хочу.Я попытался поместить цель в скрытый iFrame, который предотвращает перенаправление, но мне не удается получить доступ к результату в теле iFrame ...

Что я хочу: сделать HTTP-запрос, аналогичныйтот, который сделан по форме.Итак, я попробовал:

<html>

<head> </head>

<body>
  <form enctype="multipart/form-data" norm="form" id="myForm">
    Select a file:
    <input id="fileInput" type="file" name="upload" accept="image/png, image/jpeg, image/jpg" />
    <input type="submit" value="Start upload" />
    <label class="button-upload" onclick="send()">Upload</label>
  </form>

</body>
<script>
  var _file = null;

  function send() {
    var file = document.getElementById("fileInput").files[0]
    console.log(file)
    var url = "http://localhost:8080/solve";

    var xhr = new XMLHttpRequest();
    xhr.open("POST", url, true);
    xhr.setRequestHeader(
      "Content-Type",
      "multipart/form-data; boundary=---------------------------169461201884497922237853436"
    );
    var formData = new FormData();

    xhr.onreadystatechange = function() {
      if (xhr.readyState == 4 && xhr.status == 200) {
        alert(xhr.responseText);
      }
    };
    formData.append("upload", file);
    xhr.send(formData);
  }
</script>

</html>

Я проверил с помощью инструмента developper в сети, и запрос, похоже, совпадает с запросом, отправленным формой, хотя бутылка не может найти файл.

file = request.files.get('upload') возвращает None и file = request.files возвращает <bottle.FormsDict object at 0x7ff437abf400>, поэтому есть что-то, но я не понимаю, как получить к нему доступ!

Любая помощь будет принята с благодарностью!

1 Ответ

1 голос
/ 24 марта 2019

Ваш код JavaScript выглядит нормально, кроме тех случаев, когда вы устанавливаете заголовки запроса с помощью xhr.setRequestHeader. FormData обрабатывает многокомпонентное кодирование для вас, вам не нужно устанавливать заголовки запроса вручную. Я только что попробовал, и, похоже, работает нормально с bottlepy.

В целом измените вашу функцию send() следующим образом:

function send() {
  var file = document.getElementById("fileInput").files[0]
  console.log(file)
  var url = "http://localhost:8080/solve";

  var xhr = new XMLHttpRequest();
  xhr.open("POST", url, true);
  var formData = new FormData();

  xhr.onreadystatechange = function() {
    if (xhr.readyState == 4 && xhr.status == 200) {
      alert(xhr.responseText);
    }
  };
  formData.append("upload", file);
  xhr.send(formData);
}
...