Отправка JSON-данных из HTML form

302
01 декабря 2018, 19:30

Сделал на Flask декоратор, который должен принимать JSON-строку из html form.

@app.route('/processjson', methods=['POST'])
    data = request.get_json(force=True)
    return jsonify(data)

Через Постман проверил POST запросом, отправив JSON-строку. Все работает. Однако, отправляя саму форму из клиента, получаю:

400 Bad Request: Failed to decode JSON object: Expecting value: line 1 column 1 (char 0)

Получается, form генерирует неверный формат.

Вот form:

<form action="/processjson" enctype="application/json" method="post">
    <input type="hidden" name="name" value="Bender">
    <input type="submit" value="TEST">
</form>

request.headers['Content-Type'] возвращает 'application/x-www-form-urlencoded'

Задача состоит в том, что я должен получать из form JSON-строку, а после неких операций отправлять JSON-строку в ту же форму.

Answer 1

Браузерные формы не поддерживают application/json. И, похоже, никогда не будут поддерживать:

Осторожно! Эта спецификация не поддерживается, и HTML Working Group не хочет поддерживать её в будущем.

Можно отправлять запросы с application/json джаваскриптом. В самых простейших key/value случаях можно просто пройтись по FormData и собрать все ключики в объект, который потом закодировать в json и отправить:

document.getElementById('benderform').addEventListener('submit', submitForm); 
 
 
function submitForm(event) { 
    // Отменяем стандартное поведение браузера с отправкой формы 
    event.preventDefault(); 
 
    // event.target — это HTML-элемент form 
    let formData = new FormData(event.target); 
 
    // Собираем данные формы в объект 
    let obj = {}; 
    formData.forEach((value, key) => obj[key] = value); 
     
    // Собираем запрос к серверу 
    let request = new Request(event.target.action, { 
        method: 'POST', 
        body: JSON.stringify(obj), 
        headers: { 
            'Content-Type': 'application/json', 
        }, 
    }); 
     
    // Отправляем (асинхронно!) 
    fetch(request).then( 
        function(response) { 
            // Запрос успешно выполнен 
            console.log(response); 
            // return response.json() и так далее см. документацию 
        }, 
        function(error) { 
            // Запрос не получилось отправить 
            console.error(error); 
        } 
    ); 
 
    // Код после fetch выполнится ПЕРЕД получением ответа 
    // на запрос, потому что запрос выполняется асинхронно, 
    // отдельно от основного кода 
    console.log('Запрос отправляется'); 
}
<form action="/processjson" id="benderform"> 
  <input type="hidden" name="name" value="Bender"> 
  <input type="submit" value="TEST"> 
</form>

(Конечно, в реальности всё должно выглядеть не так топорно, как в этом примере (и вообще этот пример не работает, потому что в сниппетах Stack Overflow не предусмотрено тестирование ajax-запросов), но направление для дальнейших действий я дал.)

Документация: FormData, Fetch, async/await, XMLHttpRequest (если нужна поддержка старых браузеров)

READ ALSO
Перенос строки в pug

Перенос строки в pug

Есть чекбокс:

860
Нужно привязать клавишу клавиатуры к button с помощью javascript

Нужно привязать клавишу клавиатуры к button с помощью javascript

Пишу javascript приложение, нужно каждую клавишу компьютера привязать к определенной кнопкеХочу создать на подобие драмм-машины

329
отправить html - письмо с помощью the bat

отправить html - письмо с помощью the bat

Вопрос к знатокам the bat, как правильно отправить сверстанное html письмо?

275
Связываем 2 selecta через js

Связываем 2 selecta через js

Вообщем у меня есть 2 select`а и у каждого из них есть on change, так вот мне надо когда я передал данные из одного select в другой, этот on change запустить...

252