ruby-on-rails 如何在中间件rails中访问params变量5

tjvv9vkg  于 2023-06-07  发布在  Ruby
关注(0)|答案(4)|浏览(250)

我在使用rails 5中的中间件时遇到了一个问题,我试图通过使用中间件中的Rack::Request来操作POST http中发送的参数,但是发送的参数直到调用@app.call(env)函数才被弹出。
使用byebug访问变量envrequest,结果如下:

(byebug) env.each{|key, value| p "#{key} --> #{value}"}
 "rack.version --> [1, 3]"
 "rack.errors --> #<IO:0x007fa00209eaa8>"
 "rack.multithread --> true"
 "rack.multiprocess --> false"
 "rack.run_once --> false"
 "SCRIPT_NAME --> "
 "QUERY_STRING --> "
 "SERVER_PROTOCOL --> HTTP/1.1"
 "SERVER_SOFTWARE --> puma 3.6.2 Sleepy Sunday Serenity"
 "GATEWAY_INTERFACE --> CGI/1.2"
 "REQUEST_METHOD --> POST"
 "REQUEST_PATH --> /some_path"
 "REQUEST_URI --> /some_path"
 "HTTP_VERSION --> HTTP/1.1"
 "HTTP_CACHE_CONTROL --> no-cache"
 "HTTP_POSTMAN_TOKEN --> 5a8514ac-9050-433e-be71-80316aa01e53"
 "CONTENT_TYPE --> application/json"
 "HTTP_AUTHORIZATION --> some_token"
 "HTTP_USER_AGENT --> PostmanRuntime/3.0.9"
 "HTTP_ACCEPT --> */*"
 "HTTP_HOST --> localhost:3000"
 "HTTP_COOKIE --> _session_id=session_id"
 "HTTP_ACCEPT_ENCODING --> gzip, deflate"
 "CONTENT_LENGTH --> 144"
 "HTTP_CONNECTION --> keep-alive"
 "SERVER_NAME --> localhost"
 "SERVER_PORT --> 3000"
 "PATH_INFO --> some_path"
 "REMOTE_ADDR --> ::1"
 "puma.socket --> #<TCPSocket:0x007fa008a1bc88>"
 "rack.hijack? --> true"
 "rack.hijack --> #<Puma::Client:0x007fa008a1bc60>"
 "rack.input --> #<StringIO:0x007fa008a1a4c8>"
 "rack.url_scheme --> http"
 "rack.after_reply --> []"
 "puma.config --> #<Puma::Configuration:0x007fa0021963e8>"
 "action_dispatch.parameter_filter --> [:password]"
 "action_dispatch.redirect_filter --> []"
 "action_dispatch.secret_token --> "
 "action_dispatch.secret_key_base --> some key"
 "action_dispatch.show_exceptions --> true"
 "action_dispatch.show_detailed_exceptions --> true"
 "action_dispatch.logger --> #<ActiveSupport::Logger:0x007fa00256be78>"
 "action_dispatch.backtrace_cleaner --> #    <Rails::BacktraceCleaner:0x007fa00224e560>"
 "action_dispatch.key_generator --> #<ActiveSupport::CachingKeyGenerator:0x007fa006231858>"
 "action_dispatch.http_auth_salt --> http authentication"
 "action_dispatch.signed_cookie_salt --> signed cookie"
 "action_dispatch.encrypted_cookie_salt --> encrypted cookie"
 "action_dispatch.encrypted_signed_cookie_salt --> signed encrypted cookie"
 "action_dispatch.cookies_serializer --> json"
 "action_dispatch.cookies_digest --> "
 "action_dispatch.routes --> #<ActionDispatch::Routing::RouteSet:0x007fa002d59680>"
 "ROUTES_70162609523520_SCRIPT_NAME --> "
 "ORIGINAL_FULLPATH --> some_path"
 "ORIGINAL_SCRIPT_NAME --> "
 "action_dispatch.request_id --> e57576a4-5418-49f6-abaa-c49c5f7727a7"
 "action_dispatch.remote_ip --> ::1"
 "rack.session --> #<ActionDispatch::Request::Session:0x007fa008a314e8>"
 "rack.session.options --> #<ActionDispatch::Request::Session::Options:0x007fa008a31498>"

正如你在CONTENT_LENGTH中看到的,值144被删除,但是当你执行request.params命令时,它是空的。

(byebug) request.params
{}

然后,如果我在执行@app.call(env)行时继续byebug,则会处理参数。

Processing by Api::SomeController#some_function as JSON
Parameters: {"some_params"=>{"param1"=>"1", "param2"=>"2", "param3"=>"3"}

这是中间件代码:

class SomeMiddleware
  def initialize(*args)
    @args = args
  end
  def call(env)
    "#{self.class}::Logic".constantize.new(*@args).call(env)
  end
  class Logic
    def initialize(app, additional=nil)
      @app        = app
      @additional = additional
    end

    def call(env)
      request = Rack::Request.new(env)
      request.params
      byebug
      @app.call(env)
    end
  end
end
5t7ly7z5

5t7ly7z51#

您可以尝试从env构建请求

def call(env)
  request = Rack::Request.new(env)
  request.params
end

编辑

我觉得问题出在"REQUEST_METHOD --> POST"
因为它是POST,所以参数在主体中...
request.body.read可以访问它们。

lmvvr0a8

lmvvr0a82#

这将允许您查看正在发送的参数:

params = Rack::Utils.parse_query(env['rack.input'].read, "&")
8dtrkrch

8dtrkrch3#

这对我很有效:

class MyClass

  def initialize(app)
    @app = app
  end
  
  def call(env)
    request = Rack::Request.new(env)
    request.params['my-param']
  end
end
n8ghc7c1

n8ghc7c14#

对我很有效

params = JSON.parse(env['rack.input'].read.blank? ? {} : env['rack.input'].read)

就这样,我找到了尸体上的参数

request = Rack::Request.new(env)
request.params

使用Rack::Request,我找到了URL上的参数

相关问题