Вот общий шаблон в моих действиях контроллера:
respond_to do |format|
format.html {}
format.js {
render :layout => false
}
end
Т.е. если запрос будет не-Ajax, то я отправлю содержимое HTML в расположении на совершенно новой странице. Если запросом будет Ajax, то я отправлю вниз то же содержание, но без расположения (так, чтобы это могло быть вставлено в существующую страницу или помещено в лайтбокс или безотносительно).
Таким образом, я всегда возвращаю HTML в format.js
часть, все же направляющие устанавливают заголовок ответа Типа контента на text/javascript
. Это заставляет IE бросать это забавное небольшое сообщение об ошибке:
Конечно, я мог установить тип контента ответа каждый раз, когда я сделал это (или используйте after_filter
или безотносительно), но кажется, что я пытаюсь сделать что-то относительно стандартное, и я не хочу добавлять дополнительный шаблонный код.
Как я решаю эту проблему? С другой стороны, если единственный способ решить проблему состоит в том, чтобы изменить тип контента ответа, что лучший способ состоит в том, чтобы достигнуть поведения, которое я хочу (т.е. отправляющий вниз содержание с расположением для не-Ajax и то же содержание без расположения для Ajax), не имея необходимость иметь дело с этими ошибками?
Править: Это сообщение в блоге имеет еще некоторую информацию
IE не понимает ответ как HTML. Так что либо вы меняете заголовок ответа, либо проверяете изменение метода запроса на GET.
Корень вашей проблемы заключается в prototype Автоматическая оценка ответа JavaScript: http://api.prototypejs.org/ajax/ajax/request.html
Ваши вызовы link_to_remote
генерируют фрагмент js, похожий на:
<a href="#" onclick="
new Ajax.Updater('posts', '/blog/destroy/3', {
asynchronous:true,
evalScripts:true
}); return false;
">Delete this post</a>
Если вам не нужно оценивать ответ нигде в вашем приложении, вы можете глобально переопределить помощник link_to_remote
для генерации JS без evalScripts: true
Если u по-прежнему нужно оценивать ответ в некоторых частях, создайте собственный помощник link_to_remote_no_eval
, который не генерирует JS с evalScripts: true
, то есть:
<a href="#" onclick="
new Ajax.Updater('posts', '/blog/destroy/3', {
asynchronous:true
}); return false;
">Delete this post</a>
В таком случае, почему бы не использовать настраиваемый тип содержимого?
Mime::Type.register "text/html-piece", :html_piece
# add to view in jquery call instead of "text/javascript"
# then in your controller action
def show
respond_to do |format|
format.html { }
format.html_piece { } # no longer js mime so no IE error
end
end
Если вы пытаетесь отправить обратно HTML, вам нужно сделать:
render(:update) do |page|
page['someDomId'].replace/replace_html(render(:partial => '/partial/path'))
end
Пусть PrototypeJS делает то же, что и на фронт-энде, и ваш DOM id будет заменен автоматически. Обратите внимание, что replace заменит DOM id этим содержимым, replace_html заменит только innerHTML.
Проблема в том, что ответ отправляет заголовок Content-Type
как text / javascript
, который IE затем пытается интерпретировать как javascript, отсюда отсутствует сообщение об ошибке «)». Вам необходимо, чтобы сервер отправлял ответ в виде типа text / html
, чтобы браузер не пытался анализировать и выполнять содержимое ответа как сценарий, но позволял вам использовать его как блок HTML.
Вы можете сделать это в Rails, добавив что-то вроде следующего в один из ваших контроллеров:
@headers["Content-Type"] = "text/html"
Например, вы можете добавить это в свой Application Controller следующим образом:
class ApplicationController < ActionController::Base
before_filter :fix_ct
def fix_ct
@headers["Content-Type"] = "text/html"
end
end
в прошлом я сталкивался с подобными проблемами с IE. Вот как я решил эту проблему
if request.xhr?
render 'report', :layout => false
else
render 'report'
end
Это работает для вас?
respond_to do |format|
format.html { :layout => false if request.xhr? }
format.js {}
end
А затем вызовите ответ как HTML, а не JS (хотя я его не тестировал).
В основном, request.xhr? ключ к этому решению