我正在通过render_to_string
生成一个小表单,由于某种原因,CSRF令牌没有正确生成(即它与标题不同,用户在提交时注销,以及“可以” t在日志上验证CSRF令牌。这是相关的代码:
控制器:
def publish
@question = @event.questions.find(params[:id])
@question.update_attribute(:published, true) unless @question.published?
Pusher[@event.to_param].trigger('new_question', question: render_question)
redirect_to event_path(@event)
end
private
def render_question
render_to_string('questions/_unanswered_question', locals: {question: @question}, layout: false)
end
def fetch_event
@event ||= current_user.events.find(params[:event_id])
end
我正在使用Pusher,但您可以假设这只是使用此Javascript在页面上呈现:
$("#questions").append(data.question); // data is what I send from Pusher.
最后,部分呈现:
.answer
= form_for [@event, question, question.answers.new] do |f|
%h2
= question.title
%ul
- (1..5).each do |n|
- if question.send("answer_#{n}").present?
%li
= f.radio_button :option, n, id: "q_#{question.id}_answer_option_#{n}"
= f.label question.send("answer_#{n}"), for: "q_#{question.id}_answer_option_#{n}"
%p
= f.submit "Answer"
这可以正常工作而不会附加到页面,但会在布局中呈现。请注意,这不是一个远程表单。
答案 0 :(得分:0)
看起来您正在使用ajax生成表单,然后将其添加到Dom。为每个请求生成新的csrf令牌。据我所知,您必须使用标头中可用的csrf标记,并使用js替换表单中的标记。
应该是这样的:
success: ()->
parameter = $("meta[name=csrf-param]").attr("content")
token = $("meta[name=csrf-token]").attr("content")
question = $(data.question).find("[name="+parameter+"]").val(token)
目前我没有计算机可以先测试,所以希望我是对的:/