$.jsonCall приводит к ошибке, но получает правильные данные

Мой $.jsonCall потерпел неудачу и преуспел в то же время.

index.js

afterConstruct: function(self) {
  self.pushAsset('script', 'form', { when: 'always' });

  self.route('post', 'submit', function(req, res) {
    res.send('Submitted! ' + req.body.hello);
  });
}

form.js

(function( $ ) {
  $('.crstn-privacy form').submit(function(event) {
    event.preventDefault();

    $.jsonCall('/modules/privacy-widgets/submit', {
      hello: 'world'
    }, function(data) {
      console.log('Success:');
      console.log(data);
    }, function(err) {
      console.log('Error.');
      console.log(err);
    });
  });
})( jQuery );

widget.html

<div class="crstn-privacy">
  Privacy
  <form data-contact-form>
    <button type="submit">Submit</button>
  </form>
</div>

Функция error возвращает объект со статусом 200 и правильный ответ: Submitted! world

Почему функция успеха не выполняется?

2 ответа

Решение

Цель jsonCall последовательно выполнять все следующие действия:

  1. По умолчанию отправьте запрос через метод POST, который подходит для API-интерфейсов, подобных RPC, где кэширование может вызвать только непредвиденную боль. Это отличается от getJSON,

  2. Также отправляйте данные тела запроса в формате JSON, что позволяет точно отправлять на сервер все типы JSON, в отличие от текстовой обработки традиционных данных формы и ее хаков для отправки объектов и массивов. Это более эффективно, хотя сервер, конечно же, не должен доверять ему.

  3. И да, ожидайте, что ответ будет в формате JSON.

Причиной возникновения ошибки является то, что вы не отправляете JSON в браузер. Обратите внимание, что мы говорим о плагине на стороне браузера, он не может контролировать то, что вы делаете на стороне сервера, эта часть зависит от вас.

Так что, почему вы должны позвонить JSON.stringify сам:

Express (на который наложен Apostrophe) достаточно умен, чтобы автоматически кодировать объекты и массивы как JSON, если вы передаете их res.send, Но если ты res.send Строка, поведение по умолчанию - отправлять эту литеральную фактическую строку, что полезно в других типах маршрутов, которые отвечают фрагментами HTML или аналогичными.

Наша типичная практика - делать что-то вроде этого:

res.send({ status: 'ok', message: 'my message here' })

И на стороне браузера, посмотрите на result.message после первой проверки того, что result.status является ok, result будучи, конечно, объектом, который мы получили через jsonCall,

Резонно спросить, почему мы не используем подход REST? Причина в том, что REST не всегда сопоставляет один к одному с ошибками, которые могут возникнуть, и мы обнаружили, что более разумно использовать более гибкое поле состояния. Ваши предпочтения могут отличаться, и, конечно, никто не мешает вам писать свои маршруты и общаться с ними через window.fetch, $.post или что-нибудь плывет твоя лодка. $.jsonCall, self.api а также self.html (последние два в коде, который расширяет проигрыватели виджетов и модалы) - удобство. Используйте их, если хотите.

Надеюсь, что это полезно!

$.jsonCall() требует, чтобы ответ был JSON. Ошибка в том, что он не может разобрать ответ. использование JSON.stringify() при отправке ответа:

afterConstruct: function(self) {
  self.pushAsset('script', 'form', { when: 'always' });

  self.route('post', 'submit', function(req, res) {
    res.send(JSON.stringify('Submitted! ' + req.body.hello));
  });
}
Другие вопросы по тегам