Ruby on rails 使用超链接在rails中发出POST请求

Ruby on rails 使用超链接在rails中发出POST请求,ruby-on-rails,forms,post,hyperlink,Ruby On Rails,Forms,Post,Hyperlink,我需要一个页面上的链接,每个链接使一个帖子到不同的控制器。但是,当我使用普通链接时,会出现ActionController::InvalidAuthenticationToken错误。我理解这是因为缺少了真实性标识值。但我不想使用表单来发布帖子,因为我希望它们是链接而不是按钮。事实上,我想要完全控制链接和按钮的样式,但我不想这样做。做这些事情的标准方法是什么?你有很多选择 检查时禁用:防止伪造:仅=>[] 将onclick处理程序分配给链接,并使用javascript提交隐藏表单 在生成视图时抓

我需要一个页面上的链接,每个链接使一个帖子到不同的控制器。但是,当我使用普通链接时,会出现ActionController::InvalidAuthenticationToken错误。我理解这是因为缺少了真实性标识值。但我不想使用表单来发布帖子,因为我希望它们是链接而不是按钮。事实上,我想要完全控制链接和按钮的样式,但我不想这样做。做这些事情的标准方法是什么?

你有很多选择

  • 检查时禁用:
    防止伪造:仅=>[]
  • 将onclick处理程序分配给链接,并使用javascript提交隐藏表单
  • 在生成视图时抓取,并将其添加为请求参数

  • 顺便问一下,您如何仅使用“href”属性发出“post”请求?我认为表单是必须的。

    从技术上讲,您应该使用按钮和表单来处理任何非
    获取的内容;超链接故意不允许使用除
    GET
    以外的方法(没有像
    \u method
    参数这样的黑客)。一个非常实际的原因是,有时,“web加速器”浏览器加载项会预取页面中的链接;如果GET链接启动了一个变异操作,则可能会错误地修改用户或资源状态

    也就是说,你可以设计按钮的样式,使其行为类似于链接;我使用下面这样的方法来做得很好。它假设一个正确的CSS重置,边距和填充以及所有好的东西都被置零

    input.restlink {
      border: 0;
      background: #fff;
      color: #236cb0;
      cursor: pointer;
    }
    input.restlink:hover {
      text-decoration: underline;
    }
    

    有了这样的规则,您可以使用
    :post%>
    ,它的外观和行为就像一个链接一样好。

    如果您不反对使用jQuery和一些ajax'n,我有一个解决方案

    如果你想要一个高层次的概述,这里有一些基本信息

    将此选项添加到布局中:

    <%= javascript_tag "var AUTH_TOKEN = #{form_authenticity_token.inspect};" if protect_against_forgery? %>
    
    将此添加到应用程序控制器:

    before_filter :correct_safari_and_ie_accept_headers
    after_filter :set_xhr_flash
    
    protected
        def set_xhr_flash
          flash.discard if request.xhr?
        end
    
        def correct_safari_and_ie_accept_headers
          ajax_request_types = ['text/javascript', 'application/json', 'text/xml']
          request.accepts.sort!{ |x, y| ajax_request_types.include?(y.to_s) ? 1 : -1 } if request.xhr?
        end
    
    在你看来:

    <%= link_to "Delete", delete_product_path(product), :class => 'delete' %>
    

    本例执行删除操作,但处理POST或PUT的过程实际上是相同的。这篇博文有一个完整的示例应用程序来演示这一点。

    如果您使用的是jQuery,还可以执行以下操作:

    <!--  in your view --> 
    <%= form_tag( user_free_dates_path(:user_id => @user.id), :remote => true ) do |f| %>
      <%= hidden_field_tag :date, current_day.to_s(:short_db)  %>
      <%= link_to "Allow", "#", :class => "submit"%>
    <% end %>        
    
    // in application.js
    $("form a.submit").live("click", function(){
      $(this).closest("form").submit();
      return false;
    }); 
    
    
    @user.id),:remote=>true)do | f |%>
    “提交”%>
    //在application.js中
    $(“form a.submit”).live(“单击”,函数(){
    $(this).最近的(“表单”).submit();
    返回false;
    }); 
    
    这样做的目的是在视图中构建一个“真实”的表单,而不需要提交按钮。然后,带有“submit”类的链接将触发表单提交。最终结果看起来像一个链接,但实际上是一个表单。我相信使用原型也有类似的方法


    在我的示例中,user\u free\u dates\u path(:user\u id=>@user.id)只是一个路径帮助器,而hidden\u field\u标记是我在POST请求中传递的参数之一。

    大量借用了这些答案/来源

    获取一个看起来像链接但功能像按钮的按钮。在我的应用程序/helpers/application_helper.rb中:

    def button_as_link(action, link_text, hiddens)
        capture do
            form_tag(action, :class => 'button_as_link') do
                hiddens.each { |k, v| concat hidden_field_tag(k.to_sym, v) }
                concat submit_tag(link_text)
            end
        end
    end
    
    CSS:

    最后在我的模板中,我调用按钮作为链接函数:

    button_as_link('/some/path',{:key1=>:val1,:key2=>:val2}, 'text to display')
    

    Rails允许您指定一个
    \u method=(PUT | POST | DELETE)
    查询参数,它将解释请求,就好像它是用该方法发出的一样。它主要是为了支持
    PUT
    /
    DELETE
    ,而这并不完全支持浏览器。我真的不知道在检查时禁用的安全含义。不过,我可以尝试将其添加为请求参数。但是POST是在不同的控制器上完成的,而不是创建此视图的控制器。这有关系吗?这个令牌的范围是什么?据我所知,AT是为特定会话创建的。所以,它应该起作用。无论如何,这很容易尝试:“我的url?真实性”\u token=”我考虑过这个问题,但没有成功,因为当你按下按钮时,仍然会有令人讨厌的按键效果;在某些浏览器上,它周围有一条虚线。如果CSS重置正确,这两种情况都不会发生。您可以为显示脏矩形的浏览器设置
    outline:none
    def button_as_link(action, link_text, hiddens)
        capture do
            form_tag(action, :class => 'button_as_link') do
                hiddens.each { |k, v| concat hidden_field_tag(k.to_sym, v) }
                concat submit_tag(link_text)
            end
        end
    end
    
    form.button_as_link {
      display: inline;
    }
    
    /* See https://stackoverflow.com/a/12642009/326979 */
    form.button_as_link input[type="submit"], form.button_as_link input[type="submit"]:focus, form.button_as_link input[type="submit"]:active {
      /* Remove all decorations to look like normal text */
      background: none;
      border: none;
      display: inline;
      font: inherit;
      margin: 0;
      padding: 0;
      outline: none;
      outline-offset: 0;
      /* Additional styles to look like a link */
      color: blue;
      cursor: pointer;
      text-decoration: underline;
    }
    /* Remove extra space inside buttons in Firefox */
    form.button_as_link input[type="submit"]::-moz-focus-inner {
      border: none;
      padding: 0;
    }
    
    button_as_link('/some/path',{:key1=>:val1,:key2=>:val2}, 'text to display')