【问题标题】:How to send a DELETE Request to the browser in RoR 4如何在 RoR 4 中向浏览器发送 DELETE 请求
【发布时间】:2015-01-21 15:05:10
【问题描述】:

我正在编写 Michael Hartl 的 Ruby on Rails 教程(我是菜鸟)。

在应用程序中我想删除一条微博,但每当我尝试在浏览器中执行它时,它都会告诉我存在路由错误。 "没有路线匹配 [GET] "/microposts/3"

这是我在 _micropost.html.erb 中的代码

<tr>
    <td class="micropost">
        <span class="content"><%= micropost.content %></span>
        <span class="timestamp">
            Posted <%= time_ago_in_words(micropost.created_at) %> ago
        </span>
    </td>
    <% if current_user?(micropost.user) %>
    <td>
        <%= link_to "delete", micropost, :method => :delete,
                                         :confirm => "You sure?",
                                         :title => micropost.content %>
    </td>
    <% end %>
</tr>
</tr>

我已经有了根据书本伪造请求的 Javascript 代码

<head>
  <title><%= title %></title>
  <%= csrf_meta_tag %>
  <%= render 'layouts/stylesheets' %>
  <%= javascript_include_tag :all %>
</head>

这是我的路线的一部分。rb

Rails.application.routes.draw do

  get 'sessions/new'

  resources :users
  resources :sessions, :only => [:new, :create, :destroy]
  resources :microposts, :only => [:create, :destroy]

  match '/signup', :to => 'users#new', via: [:get, :post]
  match '/signin', :to => 'sessions#new', via: [:get, :post]
  match '/signout', :to => 'sessions#destroy', via: [:get, :post]
  match '/contact', :to => 'pages#contact', via: [:get, :post]
  match '/about', :to => 'pages#about', via: [:get, :post]
  match '/help', :to => 'pages#help', via: [:get, :post]
  match '/:id', :to => 'users#show', via: [:get, :post]

  root :to => 'pages#home'

这里是 application.js

// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file.
//
// Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require_tree .

还有 micropost_controller.rb

class MicropostsController < ApplicationController

    before_filter :authenticate, :only => [:create, :destroy]
    before_filter :authorized_user, :only => :destroy

    def create
        @micropost = current_user.microposts.build(micropost_params)
        if @micropost.save
            flash[:success] = "Micropost created!"
            redirect_to root_path
        else
            @feed_items = []
            render 'pages/home'
        end
    end

    def destroy
        @micropost.destroy
        redirect_back_or root_path
    end

    private
        def micropost_params
            params.require(:micropost).permit(:content)
        end

        def authorized_user
            @micropost = Micropost.find(params[:id])
            redirect_to root_path unless current_user?(@micropost.user)
        end
end

我已经建立了这个答案,但“button_to”方法似乎无法解决我的问题:Delete link sends "Get" instead of "Delete" in Rails 3 view

非常感谢您的任何回答。

【问题讨论】:

  • MicropostsController 中有方法destroy 吗?
  • 你的控制器代码是什么样的?您是否尝试过使用logger.info "abcde" 添加日志记录以查看发生了什么?在将请求重定向到其他地方之前,该请求可能会到达控制器。另外,我不确定为什么 Javascript 在这里有任何相关性?
  • 粘贴你的控制器方法。看起来您正在尝试在销毁后进行渲染。
  • 我刚刚粘贴了 MicropostController。
  • 嗯...我最初认为这可能是控制器问题,但您在此处发布的所有内容似乎都很好。我想说@glyuck 给出的答案可能是正确的——确保你的浏览器中启用了 Javascript(不要忘记 NoScript 等扩展!)并检查你的浏览器控制台是否有错误。在大多数浏览器中,您可以通过按 F12 来查看控制台 - 请注意,如果您导航到页面后打开控制台,您可能需要按 F5 刷新才能看到任何内容。

标签: javascript ruby-on-rails ruby ruby-on-rails-4


【解决方案1】:

确保你有

//= require jquery
//= require jquery_ujs

在您的application.js 中。页面加载后还要查看浏览器的 javascript 控制台。也许有一些 javascript 错误,它们可以阻止 jquery_ujs 工作。

另外,请注意您需要将:confirm =&gt; "You sure?" 更改为:data=&gt; {:confirm =&gt; "You sure?"}

解释: RUBY尝试成为 RESTful,所以它发送edit 操作的 PATCH 请求,destroy 操作的 DELETE 请求。但大多数浏览器只能提交 GET 和 POST 表单。超链接总是通过 GET 打开(并且 link_to 生成 &lt;a href=...&gt; 标签)。因此,rails 会做一些黑客行为并“模拟”DELETE、PUT 和 PATCH 请求。

form_tag helper 创建额外的隐藏输入:&lt;input name="_method" type="hidden" value="delete" /&gt;,然后 Rails 解析请求参数并假定它是 DELETE 请求。你可以阅读它in documentation

link_to 'delete', '/some/url', :method =&gt; :delete 将生成以下 html:&lt;a href="/some/url/" data-method="delete"&gt;delete&lt;/a&gt;。然后jquery_ujs javascript 拦截所有对带有data-method 属性的链接的点击,并使用method="POST" 创建隐藏表单,是的,使用name="_method" value="delete" 隐藏输入,然后提交此表单。看看jquery_ujssource code,还是比较直接的。

SO如果您在单击method: :destroy 链接后在服务器控制台中看到 GET 请求,则很可能是 javascript 存在一些问题。

【讨论】:

  • 如果这是一个路由错误 (Routing Error. "No route matches [GET] "/microposts/3") 那么它可能是服务器端问题,而不是浏览器端问题。
  • 为什么要投反对票?这绝对是javascript问题。 :delete 链接不应通过 GET 打开。 jquery_ujs 使用&lt;input name="_method" value="delete" type="hidden" /&gt; 创建隐藏的 POST 表单并提交它。另外请注意,您需要将:confirm =&gt; "You sure?" 更改为:data=&gt; {:confirm =&gt; "You sure?"}
  • OP 代码包含&lt;%= link_to "delete", micropost, :method =&gt; :delete,因此即使 实际 HTTP 方法不同,Rails 也应将其视为 DELETE 请求(而不是 GET)。
  • @GoBusto,尝试从您的application.js 中删除jquery_ujs 并点击:method =&gt; :delete 的链接。令人惊讶的是,您的浏览器会发送 GET 请求。仅供参考,如果没有 javascript,大多数浏览器只能发送 GET 和 POST 请求。请在此处阅读更多信息:guides.rubyonrails.org/… 和此处:github.com/rails/jquery-ujs/blob/master/src/rails.js#L170
  • 啊,抱歉,我误解了你的意思——我以为你是在暗示这是一个与 AJAX 相关的问题,而不是一个带有 Javascript 的伪造 HTTP 动词问题。 (我确实知道大多数浏览器只支持 GET 和 POST,顺便说一下 - 这就是我在 :method =&gt; :delete 评论中所指的内容)。无论如何,考虑取消我的反对票!
猜你喜欢
  • 2021-07-15
  • 1970-01-01
  • 2013-08-13
  • 2019-03-30
  • 1970-01-01
  • 2013-06-09
  • 1970-01-01
  • 2011-08-21
  • 1970-01-01
相关资源
最近更新 更多