ajax post-запрос отвечает элементом html при включении вложения со скрепкой - PullRequest
0 голосов
/ 17 февраля 2012

Вопрос новичку, так что, пожалуйста, держись со мной ...

У меня есть приложение, которое позволяет пользователям отправлять истории через ajax, а затем позволяет читателям комментировать истории с постами, также отправленными через ajax. Я использую Rails 3.0.3, ruby ​​1.9.2p290 и jquery 1.6.22. Я также позволяю пользователям добавлять фотографии в свои сообщения с помощью скрепки rails paperclip 2.3.

Все отлично работает, когда пользователь не включает фотографию в свои посты. Я получаю код ответа 200 от сервера, и сервер отвечает с правильным JSON, который я могу проанализировать без проблем. Моя проблема возникает, когда пользователь включает фотографию.

Когда пользователь включает фотографию, я все равно получаю код ответа сервера 200, но по какой-то причине реальный ответ от сервера находится в формате HTML, а не в формате json (вызывая ошибку parsererror). Какой должен быть ответ json, затем включается в элемент HTML. Я могу взломать html, чтобы получить нужные мне данные, но я бы предпочел сделать это правильно, если сервер вернет действительный json вместо json внутри HTML.

Вот соответствующий код:

application.js:

jQuery.ajaxSetup({ 
  beforeSend: function(xhr) {
    xhr.setRequestHeader("Accept", "text/javascript")
  }
});

////show "please wait" icon when submitting a form via ajax or remotipart
$(document).delegate("form", "ajax:beforeSend ajax:remotipartSubmit", function(e, data, status, xhr){
  $("div.loading_new").attr('style', 'z-index: 9999');
});

//remove the "please wait" icon when the ajax request completes
$(document).delegate("form.new_post", "ajax:complete", function(e, data, status, xhr){
    $("div.loading_new_post").attr('style', '');
});

//immediately add a new post on successful ajax post request    
$(document).delegate("form.new_post", "ajax:success", function(e, data, status, xhr){
    pollingForNewPosts();  //immediately poll for new posts even if the polling timer hasn't tolled yet
    $("#bucket_for_new_post_form_story_"+data.post.story_id).slideUp(); 
    $("#bucket_for_new_post_form_story_"+data.post.story_id).empty();
});

Обратите внимание, что когда я отправляю запрос на публикацию без фотографии, срабатывает как успешный, так и полный обратный вызов. Когда я отправляю сообщение с фотографией, срабатывает только полный обратный вызов.

posts_controller.rb:

 def create
    @story = Story.find(params[:story_id])
    @post = @story.posts.build(params[:post])
    @post.user_id = current_user.id
    if @post.save 
      logger.debug "!!!!! #{@post.to_json}"
      render :json => @post
    end
 end

Вот консольный вывод для сообщения без вложения, за которым следует сообщение с вложением. Как видите, оба вывода отражают действительный json без какой-либо оболочки HTML:

enter image description here

enter image description here

Вот пример формы сообщения HTML:

<form id="new_post_for_story_55" class="new_post" novalidate="novalidate" method="post" enctype="multipart/form-data" data-remote="true" action="/stories/55/posts" accept_charset="UTF-8" target="">
  <div class="field">
    <label> Add to the story: </label>
    <br>
    <textarea id="new_post_contents_for_story_55" class="new_post_contents valid" name="post[contents]"></textarea>
    <div class="loading_new loading_new_post" style="">
      <img src="images/ajax-loader.gif">
    </div>
  </div>
  <div class="field">
    If you want to add a photo to your post, browse for it here:
     <input id="new_post_photo" class="valid" type="file" name="post[photo]">
  </div>
  <div class="actions">
    <input id="post_submit_story_55" class="submit_post button ui-button ui-widget ui-state-default ui-corner-all" type="submit" aria-disabled="false" role="button" value="Submit" name="commit">
    <input id="cancel_post_button_55" class="cancel_post button ui-button ui-widget ui-state-default ui-corner-all" type="button" aria-disabled="false" role="button" value="Cancel" name="cancel">
  </div>
</form>

И вот соответствующие части моего файла post.rb:

class Post < ActiveRecord::Base

  attr_accessor 
  attr_accessible :contents, :photo, :latitude, :longitude

  belongs_to    :story, :touch => true
  belongs_to    :user, :touch => true

  has_attached_file :photo, 
                    :styles => { :medium => "400x400>", :thumb => "100x100>" },
                    :storage => :s3,
                    :s3_credentials => "#{Rails.root.to_s}/config/s3.yml",
                    :path => "/:style/:id/:filename"

  validates   :contents,  :presence   => true,
                  :length     => {  :maximum => 299,
                                :minimum => 5 } 
  validates   :user_id,   :presence => true
  validates_attachment_content_type :photo, :content_type=>['image/jpeg', 'image/png', 'image/gif']

Наконец, вот ответ, который я получаю от firebug с сообщением, которое не содержит вложения, а затем очень похожее сообщение с вложением: enter image description here

Как видите, второе сообщение с фотографией, прикрепленной с помощью скрепки, и ответ в html. Первое сообщение не имеет вложения, и его ответ - json.

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

Спасибо, что подумали об этом!

1 Ответ

0 голосов
/ 21 мая 2013

Оказывается, что remotipart использует скрытый iframe для транспортировки вашего изображения.В результате действия редактирования, получающего html-запрос, ваш сервер возвращает html-ответ.Remotipart достаточно умен, чтобы обернуть желаемый ответ JSON в HTML, и вы можете использовать $ .parseJSON (data.responseText), чтобы добраться до JSON.Но ваш браузер, который ожидает чистый ответ json, выдаст парсерор.

Я считаю, что вы можете просто проигнорировать эту ошибку.

...