【问题标题】:Routing Error with Post/Put requests (Passenger Headers)Post/Put 请求的路由错误(乘客标头)
【发布时间】:2013-01-02 02:15:01
【问题描述】:

我遇到了一个奇怪的问题,经过大量研究后无法解决。我有几种通过 Carrierwave 上传文件的表格。当我上传信息时,部分路线被切断(我认为)。

例如,我有一个多部分的表单提交给:

https:/domain/programs/223/add_file 作为 POST

但是在提交时我得到了错误

没有路由匹配 [POST] "/223/add_file"

即使我的地址栏中的内容是完整的路线。如果将完整的路线作为 GET 请求提交,它可以正常工作。当我运行 rake 路线时,路线显示得很好。

这是我的路线的一个子集:

resources :programs do
  match "add_file" => "programs#add_file"

如果重要的话,我在 Apache 上运行 Rails 3.2.2 和Passenger。该问题仅发生在此生产服务器上,从未在开发中。

有什么想法吗?我被困在这个上,因为它影响了多条路线,我尝试为该表格定义一个自定义路线,但没有运气。

更新: 当我从表单中删除 multi-part => true 或 file_field_tag 时,它可以解决问题。这仍然是一个问题,但似乎与其说是关于路由,不如说是关于文件上传的表单。

【问题讨论】:

  • 我找到了一个似乎可行的肮脏解决方案。如果我的实际路线是/programs/223/add_file,那么我的表单需要指向/programs/programs/223/add_file。这不应该工作,但可以。去图吧。
  • 你可能想查看我的帖子stackoverflow.com/questions/15178033/…
  • 这对我也有用。谢谢 - 你是一个救生员!让我的整个申请失败不在本周的议程上。如果修改有任何副作用,我会通知您。
  • 不客气,很高兴为您提供帮助)
  • 如果你不介意我添加了一个答案,那么你可以接受它作为一个正确的答案;) thx

标签: ruby-on-rails passenger


【解决方案1】:

使用此代码在lib 文件夹中创建passenger_extension.rb

乘客 3

module PhusionPassenger
  module Utils

    protected

    NULL = "\0".freeze

    def split_by_null_into_hash(data)
      args = data.split(NULL, -1)
      args.pop
      headers_hash = Hash.new
      args.each_slice(2).to_a.each do |pair|
        headers_hash[pair.first] = pair.last unless headers_hash.keys.include? pair.first
      end
      return headers_hash
    end

  end
end

5 号乘客

module PhusionPassenger
  module Utils

    # Utility functions that can potentially be accelerated by native_support functions.
    module NativeSupportUtils
      extend self

      NULL = "\0".freeze

      class ProcessTimes < Struct.new(:utime, :stime)
      end

      def split_by_null_into_hash(data)
        args = data.split(NULL, -1)
        args.pop
        headers_hash = Hash.new
        args.each_slice(2).to_a.each do |pair|
          headers_hash[pair.first] = pair.last unless headers_hash.keys.include? pair.first
        end
        return headers_hash
      end

      def process_times
        times = Process.times
        return ProcessTimes.new((times.utime * 1_000_000).to_i,
          (times.stime * 1_000_000).to_i)
      end
    end

  end # module Utils
end # module PhusionPassenger

然后在 'config/application.rb' 中执行:

class Application < Rails::Application
  ...
  config.autoload_paths += %W(#{config.root}/lib)
  require 'passenger_extension'
end

然后重启一个网络服务器。

注意:我不确定这不会破坏任何其他功能,因此使用它需要您自担风险,如果您发现这种方法有任何危害,请告诉我。

【讨论】:

  • 是的,这为我解决了问题,非常非常好的答案@trushkevich
  • 很高兴帮助别人:)
  • 嗨,我尝试使用你的修复,但它在 Rails 4.2 上不起作用,你知道是否有一些不同吗?
  • 嗨@Léo,我在 4.2 中没有遇到这个问题。仅供参考,在我的问题中,我一直在描述使用 rails 3.2 - stackoverflow.com/questions/15178033/… 的调试过程。因此,您可以应用类似的方法来找出 rails 4.2 出了什么问题
  • @Léo,检查并让我知道这个要点是否对gist.github.com/trushkevich/cc5b87e3b6f440738441 有帮助(它基于乘客 5.0.25)。这更像是一个猜测,因为我无法重现乘客 5 的问题,而且我没有足够的时间来很好地测试解决方案,但我检查了(使用 Nginx)并且可以确认上传至少以这种方式工作(没有最初有问题)。
【解决方案2】:

这里的一个问题是您没有指定路由是在集合还是成员上定义的。哪一条是正确的路线?

programs/:id/add_file

programs/add_file

你应该像这样构建你的路线:

resources :programs do
  post 'add_file', :on => :member
end

resources :programs do
  member do
    post 'add_file'
  end
end

以上将在programs/:id/add_file 接收post 请求并将它们发送到ProgramsController.add_file,并以params[:id] 作为程序ID。

如果你想在收藏中加入这个,你可以这样做:

resources :programs do
  post 'add_file', :on => :collection
end

resources :programs do
  collection do
    post 'add_file'
  end
end

这将接收programs/add_file 的帖子请求并将它们发送到ProgramsController.add_file,但不会设置params[:id]

一般而言,您应该始终指定路由是在集合上还是在成员上,并且您应该指定路由应该接受哪个动词(即使用“get”或“post”等而不是“match”)。

试试上面的方法,看看能不能解决你的问题,如果不能,请告诉我,我再看看。

【讨论】:

  • 这似乎并没有解决问题。但是感谢您区分收藏和会员,我一直不清楚。我的路线文件当然需要清理。让我感到困惑的是,在与 Rake 核对时,我的路线看起来是正确的。主要问题似乎是路线消失的一部分。所以:/programs/223/add_file 变成:/223/add_file
【解决方案3】:

我想你可能需要添加

:via => [:post]

到您的路线规范。它适用于开发而不是生产似乎很奇怪,但据我了解 Rails 路由,您添加的匹配器只会响应获取。

尝试将匹配更改为

match "add_file" => "programs#add_file", :via => [:post]

此外,根据 Andrew 刚刚提交的答案,您最好使用成员说明符来明确说明操作发生在具有特定 id 的特定程序上,而不是集合上。它还应该在您的 add_file 方法中保存一些代码,这些代码可能正在努力从 url 获取 id 参数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-25
    • 1970-01-01
    • 2021-10-03
    • 2020-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多