Rails 3.2.13 - 使用禁用的HTML表单清除会话

时间:2013-08-16 13:57:46

标签: ruby-on-rails forms session hash

我遇到问题,在提交表单时会清除会话哈希,但无法弄清楚为什么会出现这种情况。情况如下:

我的应用程序中有一些模型,其中一个称为计划。用户可以查看,编辑,删除或创建计划。当调用除视图​​之外的任何操作时,将显示一个表单,用户可以动态地向计划添加信息,并最终提交表单以在数据库中创建/更新计划。还会根据用户的输入生成输出。这部分工作正常。

当我使用已禁用的表单时,会出现此问题。当用户单击以查看现有计划时,将调用 show 操作。在视图模式下,表单基本上是只读的,所以除了Submit按钮之外,我已经禁用了所有表单的元素。最初,表格不是只读的,如果不是,我没有任何问题。用户可以查看计划并单击“提交”按钮以获得正确的输出。

现在,使用已禁用的表单,用户可以执行相同的过程,但很明显表单的信息无法修改。当用户单击相同的“提交”按钮时,表单将被处理,但输出根本不会呈现。

经过多次故障排除后,我设法弄清楚会话哈希由于某种原因被清除,导致某些逻辑无法正常工作。当用户单击以查看计划时,将调用 show 操作,单击“提交”按钮时,将调用 render_plan 操作。对于 render_plan 操作,我没有任何before_filters。在显示操作中,我将会话[:accessType] 设置为“查看”。我已经确认哈希实际上已设置。现在,当它移动到 render_plan 操作时,我已经检查了会话哈希,并且它已被完全清除。我似乎无法弄清楚为什么并且已经尝试了几个小时。

同样,当表单未被禁用时,一切正常。在以只读模式提交时,我不需要表单中的任何信息,因为我使用了计划的所有数据库存储信息而不是提交的信息。另外,我已经验证我的代码中没有语法/运行时错误。

有没有人对为什么会话哈希被清除有任何想法?我不是以任何方式清除它。在此先感谢您的帮助!


编辑#1

包含表格的'show'html.erb文件可以在下面找到:

<% if session[:accessType] != "Create" %>
    <% provide(:title, @savedPlan.name) %>

    <h1 id="pagetitle"><%= session[:accessType] %>ing: <%= @savedPlan.name %></h1>
<% else %>
    <% provide(:title, 'New Project Plan') %>

    <h1 id="pagetitle">New Project Plan</h1>
<% end %>

<div id="form_errors">
    <ul>
        <li>Please correct the errors below:</li>
        <li>&nbsp;</li>
    </ul>
</div>

<h2 class="sectiontitle">Choose the project mode.</h2>

<%# Sets the correct project mode for the saved project plan %>
<% if !@savedPlan.nil? %>
    <% if @savedPlan.projectMode == "variable" %>
        <% varChecked = 'checked=checked' %>
    <% else %>
        <% fixedChecked = 'checked=checked' %>
    <% end %>
<% else %>
    <% varChecked = 'checked=checked' %>
<% end %>

<label class="radio inline radiolabel">
    <input id="radVar" name="radMode" type="radio" value="Variable" tabindex="1" <%= if !varChecked.nil?; varChecked; end %>
           onclick="OptionChoice();"> 
    Variable
</label>

<label id="lblRadFixed" class="radio inline radiolabel">
    <input id="radFixed" name="radMode" type="radio" value="Fixed" tabindex="2" <%= if !fixedChecked.nil?; fixedChecked; end %>
           onclick="OptionChoice();">
    Fixed
</label>

<div class="variable projectmode">
    <%= form_tag({:controller => 'project_plans', :action => 'render_plan' },
                 { :multipart => true, :id => 'frmvariableplan', :name => 'frmvariableplan', :class => 'form-inline' }) do %>
        <input id="variable_project_mode" name="projectmode" value="variable" type="hidden">

        <div class="row proj-start-end-date-div">
            <div class="span4">
                <%= label_tag :projname, "Project Name", :class => 'project_date_label biglbl biglbl-spacing' %>
                <input class="proj-start-end-date input-spacing" name="projname" type="text" value="<%= if !@savedPlan.nil?; @savedPlan.name; end %>">
            </div>

            <div class="span4">
                <%= label_tag :projstartdate, "Start Date", :class => 'project_date_label biglbl biglbl-spacing' %>
                <input class="proj-start-end-date input-spacing datepicker read_only_input" name="projstartdate" type="text"
                       value="<%= if !@savedPlan.nil?; @savedPlan.startDate.strftime("%m/%d/%Y"); end %>" readonly="true">
            </div>

            <div class="span4">
                <%= label_tag :projenddate, "End Date", :class => 'project_date_label biglbl biglbl-spacing' %>
                <input class="proj-start-end-date" name="projenddate" type="text"
                       value="<%= if !@savedPlan.nil?; @savedPlan.endDate.strftime("%m/%d/%Y"); end %>" readonly="true">
            </div>
        </div>

        <!-- Horizontal Rule to break the page up into sections -->
        <hr />

        <div>
            <!-- Simple service type -->
            <label name="lblServiceType_Simple" class="biglbl servicetypeheading">Service Type: Simple</label>

            <div id="divServiceType_Simple" class="servicetypediv">
                <%= render :partial => 'project_plans/display_services', :locals => { :type_service => 'simple' } %>

                <%= render :partial => 'project_plans/add_service', :locals => { :service_type => 'simple' } %>

                <% if !@savedPlan.nil? %>
                    <% service_array_length = (@all_services_array[0].count - 1) %>                     

                    <script type="text/javascript">
                        <% if (service_array_length >= 0) %>
                            CreateSlider("simple", "Total",   0, 144, <%= @all_services_array[0][0].totalHours %>);
                            CreateSlider("simple", "Design",  0, 64,  <%= @all_services_array[0][0].designHours %>);
                            CreateSlider("simple", "Develop", 0, 80,  <%= @all_services_array[0][0].developHours %>);
                        <% else %>                      
                            CreateSlider("simple", "Total",   0, 144, 144);
                            CreateSlider("simple", "Design",  0, 64,  64);
                            CreateSlider("simple", "Develop", 0, 80,  80);
                        <% end %>
                    </script>

                    <% (0..service_array_length).each do |i| %>
                        <% service = @all_services_array[0][i] %>

                        <%= render(:partial => 'project_plans/new_service',
                                   :locals => { :type_service => 'simple', :type_count => (i + 1),
                                                :service_name => service.name, :start_date => service.startDate.strftime("%m/%d/%Y"),
                                                :end_date => service.endDate.strftime("%m/%d/%Y"),
                                                :design_endDate => service.design_endDate.strftime("%m/%d/%Y"), :priority => service.priority,
                                                :should_display_button => ((i != service_array_length) ? 'false' : 'true') }) %>
                    <% end %>

                    <% session[:simple] = @all_services_array[0].count %>
                <% else %>
                    <script type="text/javascript">
                        CreateSlider("simple", "Total",   0, 144, 144);
                        CreateSlider("simple", "Design",  0, 64,  64);
                        CreateSlider("simple", "Develop", 0, 80,  80);
                    </script>
                <% end %>
            </div>

            <!-- Horizontal Rule to break the page up into sections -->
            <hr />

            <!-- Medium service type -->
            <label name="lblServiceType_Medium" class="biglbl servicetypeheading">Service Type: Medium</label>

            <div id="divServiceType_Medium" class="servicetypediv">
                <%= render :partial => 'project_plans/display_services', :locals => { :type_service => 'medium' } %>

                <%= render :partial => 'project_plans/add_service', :locals => { :service_type => 'medium' } %>

                <% if !@savedPlan.nil? %>
                    <% service_array_length = (@all_services_array[1].count - 1) %>

                    <script type="text/javascript">
                        <% if (service_array_length >= 0) %>
                            CreateSlider("medium", "Total",   145, 220, <%= @all_services_array[1][0].totalHours %>);
                            CreateSlider("medium", "Design",  0,   100, <%= @all_services_array[1][0].designHours %>);
                            CreateSlider("medium", "Develop", 0,   120, <%= @all_services_array[1][0].developHours %>);
                        <% else %>                      
                            CreateSlider("medium", "Total",   145, 220, 220);
                            CreateSlider("medium", "Design",  0,   100, 100);
                            CreateSlider("medium", "Develop", 0,   120, 120);
                        <% end %>
                    </script>

                    <% (0..service_array_length).each do |i| %>
                        <% service = @all_services_array[1][i] %>

                        <%= render(:partial => 'project_plans/new_service',
                                   :locals => { :type_service => 'medium', :type_count => (i + 1),
                                                :service_name => service.name, :start_date => service.startDate.strftime("%m/%d/%Y"),
                                                :end_date => service.endDate.strftime("%m/%d/%Y"),
                                                :design_endDate => service.design_endDate.strftime("%m/%d/%Y"), :priority => service.priority,
                                                :should_display_button => ((i != service_array_length) ? 'false' : 'true') }) %>
                    <% end %>

                    <% session[:medium] = @all_services_array[1].count %>
                <% else %>
                    <script type="text/javascript">
                        CreateSlider("medium", "Total",   145, 220, 220);
                        CreateSlider("medium", "Design",  0,   100, 100);
                        CreateSlider("medium", "Develop", 0,   120, 120);
                    </script>
                <% end %>
            </div>

            <!-- Horizontal Rule to break the page up into sections -->
            <hr />

            <!-- Complex service type -->
            <label name="lblServiceType_Complex" class="biglbl servicetypeheading">Service Type: Complex</label>

            <div id="divServiceType_Complex" class="servicetypediv">
                <%= render :partial => 'project_plans/display_services', :locals => { :type_service => 'complex' } %>

                <%= render :partial => 'project_plans/add_service', :locals => { :service_type => 'complex' } %>

                <% if !@savedPlan.nil? %>
                    <% service_array_length = (@all_services_array[2].count - 1) %>

                    <script type="text/javascript">
                        <% if (service_array_length >= 0) %>
                            CreateSlider("complex", "Total",   221, 295, <%= @all_services_array[2][0].totalHours %>);
                            CreateSlider("complex", "Design",  0,   135, <%= @all_services_array[2][0].designHours %>);
                            CreateSlider("complex", "Develop", 0,   160, <%= @all_services_array[2][0].developHours %>);
                        <% else %>                      
                            CreateSlider("complex", "Total",   221, 295, 295);
                            CreateSlider("complex", "Design",  0,   135, 135);
                            CreateSlider("complex", "Develop", 0,   160, 160);
                        <% end %>
                    </script>

                    <% (0..service_array_length).each do |i| %>
                        <% service = @all_services_array[2][i] %>

                        <%= render(:partial => 'project_plans/new_service',
                                   :locals => { :type_service => 'complex', :type_count => (i + 1),
                                                :service_name => service.name, :start_date => service.startDate.strftime("%m/%d/%Y"),
                                                :end_date => service.endDate.strftime("%m/%d/%Y"),
                                                :design_endDate => service.design_endDate.strftime("%m/%d/%Y"), :priority => service.priority,
                                                :should_display_button => ((i != service_array_length) ? 'false' : 'true') }) %>
                    <% end %>

                    <% session[:complex] = @all_services_array[2].count %>
                <% else %>
                    <script type="text/javascript">
                        CreateSlider("complex", "Total",   221, 295, 295);
                        CreateSlider("complex", "Design",  0,   135, 135);
                        CreateSlider("complex", "Develop", 0,   160, 160);
                    </script>
                <% end %>
            </div>

            <!-- Horizontal Rule to break the page up into sections -->
            <hr />

            <!-- Incremental service type -->
            <label name="lblServiceType_Incremental" class="biglbl servicetypeheading">Service Type: Incremental</label>

            <div id="divServiceType_Incremental" class="servicetypediv">
                <%= render :partial => 'project_plans/display_services', :locals => { :type_service => 'incremental' } %>

                <%= render :partial => 'project_plans/add_service', :locals => { :service_type => 'incremental' } %>

                <% if !@savedPlan.nil? %>
                    <% service_array_length = (@all_services_array[3].count - 1) %>

                    <script type="text/javascript">
                        <% if (service_array_length >= 0) %>
                            CreateSlider("incremental", "Total",   0, 40, <%= @all_services_array[3][0].totalHours %>);
                            CreateSlider("incremental", "Design",  0, 40, <%= @all_services_array[3][0].designHours %>);
                            CreateSlider("incremental", "Develop", 0, 40, <%= @all_services_array[3][0].developHours %>);
                        <% else %>                      
                            CreateSlider("incremental", "Total",   0, 40, 40);
                            CreateSlider("incremental", "Design",  0, 20, 20);
                            CreateSlider("incremental", "Develop", 0, 20, 20);
                        <% end %>
                    </script>

                    <% (0..service_array_length).each do |i| %>
                        <% service = @all_services_array[3][i] %>

                        <%= render(:partial => 'project_plans/new_service',
                                   :locals => { :type_service => 'incremental', :type_count => (i + 1),
                                                :service_name => service.name, :start_date => service.startDate.strftime("%m/%d/%Y"),
                                                :end_date => service.endDate.strftime("%m/%d/%Y"),
                                                :design_endDate => service.design_endDate.strftime("%m/%d/%Y"), :priority => service.priority,
                                                :should_display_button => ((i != service_array_length) ? 'false' : 'true') }) %>
                    <% end %>

                    <% session[:incremental] = @all_services_array[3].count %>
                <% else %>
                    <script type="text/javascript">
                        CreateSlider("incremental", "Total",   0, 40, 40);
                        CreateSlider("incremental", "Design",  0, 20, 20);
                        CreateSlider("incremental", "Develop", 0, 20, 20);
                    </script>
                <% end %>
            </div>
        </div>

        <!-- Horizontal Rule to break the page up into sections -->
        <hr />

        <!-- Resources section -->
        <label name="lblResources" class="biglbl servicetypeheading">Resources</label>

        <div id="resources" class="servicetypediv">
            <%= render :partial => 'project_plans/add_resource' %>

            <% if !@savedPlan.nil? %>
                <% resource_array_length = (@all_resources_array.count - 1) %>

                <% (0..resource_array_length).each do |i| %>
                    <% resource = @all_resources_array[i] %> 

                    <%= render(:partial => 'project_plans/new_resource',
                               :locals => { :type_count => (i + 1), :resource_name => resource.name, :start_date => resource.startDate.strftime("%m/%d/%Y"),
                                            :end_date => resource.endDate.strftime("%m/%d/%Y"), :resource_type => resource.resourceType,
                                            :should_display_button => ((i != resource_array_length) ? 'false' : 'true') }) %>
                <% end %>

                <% session[:rescount] = @all_resources_array.count %>
            <% end %>
        </div>

        <!-- Horizontal Rule to break the page up into sections -->
        <hr />

        <div>
            <p class="biglbl">Notes:</p>

            <textarea class="span6 textarea-spacing" name="txtNotes" rows="5"
                      placeholder="Enter any notes here"><%= if !@savedPlan.nil?; @savedPlan.notes; end %></textarea>

            <input class="btn btn-primary btn-project-plan" value="<%= session[:accessType] %> Project Plan" type="button"
                   onclick="ValidateForm($('#frmvariableplan'))">
        </div>

        <div class="clearfix"></div>
    <% end %>
</div>

<div class="fixed projectmode">
    <%= form_tag({:controller => 'project_plans', :action => 'render_plan' },
                 { :multipart => true, :id => 'frmfixedplan', :name => 'frmfixedplan', :class => 'form-inline' }) do %>
        <input id="fixed_project_mode" name="projectmode" value="fixed" type="hidden">

        <div class="row proj-start-end-date-div">
            <div class="span4">
                <%= label_tag :projname, "Project Name", :class => 'project_date_label biglbl biglbl-spacing' %>
                <input class="proj-start-end-date input-spacing" name="projname" type="text">
            </div>

            <div class="span4">
                <%= label_tag :projstartdate, "Start Date", :class => 'project_date_label biglbl biglbl-spacing' %>
                <input class="proj-start-end-date input-spacing datepicker read_only_input" name="projstartdate" type="text" readonly="true">
            </div>

            <div class="span4">
                <%= label_tag :projenddate, "End Date", :class => 'project_date_label biglbl biglbl-spacing' %>
                <input class="proj-start-end-date" name="projenddate" type="text" readonly="true">
            </div>
        </div>
    <% end %>
</div>

<% if session[:accessType] == "View" %>
    <script type="text/javascript">
        disableForm($('#frmvariableplan'));
    </script>
<% end %>

* * 答案 * ***

我终于明白了!

这个问题通常不会让我想到:真实性令牌。因为我的JavaScript函数基本上禁用了表单上的每个元素,所以默认情况下Rails实现的真实性检查也被禁用。这意味着它们不会在POST请求时提交给服务器,并且Rails会将错误/丢失的真实性令牌解释为欺诈性请求。在这种情况下,会话信息将被清除,以保护您的应用程序。

想象一下像Twitter或Facebook这样的网站,您可以在其中登录,发布内容等。由于用户的登录信息存储为会话,因此只有在发出欺诈性请求时清除整个会话才有意义将有效地退出用户。

为了解决这个问题,我在禁用表单上的所有元素后,只使用JavaScript启用了两个真实性输入框:

$(document.getElementsByName("utf8")[0]).attr('disabled', false);
$(document.getElementsByName("authenticity_token")[0]).attr('disabled', false);

这就是诀窍!

1 个答案:

答案 0 :(得分:0)

在您担心会话哈希被清除之前,您是否有充分理由在展示视图中使用表单?您可以通过其他方式更轻松地显示该信息 - 您是否可以将您正在谈论的节目文件放入您的问题中?