формат rails json

#ruby-on-rails #json #jquery

#ruby-on-rails #json #jquery

Вопрос:

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

 def check_progress
  if request.xhr?
    render :json=>"{'bytes_expected': #{session[:size]}, 'bytes_recieved': #{session[:size]}, 'last_seq': 0}".to_json
  end
end
  

но в моем коде js :

 $.getScript('contacts/check_progress', function(data){
    console.log(data.bytes_recieved)
    console.log(data.bytes_expected)
    d.renderProgress(data);
});
  

Я получаю undefined в ответ на data.bytes_recieved и data.bytes_expected .

что не так в моем коде rails?

Ответ №1:

Я думаю, ваша основная проблема может заключаться в том, что вы возвращаете строку, которая выглядит как json и на самом деле не является хэшем json.

в вашей инструкции render вы вручную форматируете json в виде строки… это нормально, пока вы не вызовете для него to_json.

to_json предполагает передачу хэша, а не строки.

Вы могли бы попробовать удалить .to_json в конце вашего оператора render:

 render :json=>"{'bytes_expected': #{session[:size]}, 'bytes_recieved': #{session[:size]}, 'last_seq': 0}"
  

или создайте хэш ruby, а затем преобразуйте его в json:

 @ruby_hash = {
  :bytes_expected => session[:size],
  :bytes_recieved => session[:size],
  :last_seq => 0
}

render :json=> @ruby_hash.to_json
  

Ответ №2:

$.getScript Метод jQuery вставляет <script> узел в <head> ваш HTML-документ.

С помощью этого метода ваш браузер не будет отправлять X-Requested-With HTTP-заголовок на сервер. Потому что это будет простой HTTP-запрос, а не AJAX. И ваш браузер ожидает javascript в ответе, а не данные JSON.

В документации jQuery к $.getScript методу несколько вводит в заблуждение, потому что там говорится data , что в функции обратного вызова сигнатуры метода, но это не даст вам никаких данных в функции обратного вызова, потому что ваш браузер просто выполняет javascript, в этом запросе нет фактической полезной нагрузки.

Существует множество возможных решений:

  • Если вам нужно загрузить данные из междоменной сети, попробуйте удалить request.xhr? условие использования метода JSONP и обратного вызова
  • если это не междоменная ситуация, просто загрузите с ответом $.getJSON и не трогайте условие

Обновление: и я этого не видел, но @Barlow указал на это, вам нужно исправить код генерации json в вашем приложении rails, как он говорит.

Ответ №3:

Вы можете упростить свой код до:

 def check_progress
  if request.xhr?
    render :json => {'bytes_expected' => session[:size], 
                     'bytes_recieved' => session[:size], 
                     'last_seq' => 0}
  end
end
  

as render :json выполнит преобразование хэша в объект JSON за вас. Я не знаю, решит ли это проблему.