我的 API 正在接收一个在 POST 正文中包含 windows-1252 编码数据的调用。
在 Rails 6.0.3 中,这显然有效。但是rails 6.1.1抛出ActionController::BadRequest(无效的请求参数:参数的编码无效。
编辑:我无法将调用更改为 UTF-8,这些调用来自第 3 方。因此,我的 API 必须接受 windows-1252 编码。
这是模拟此调用的片段:
require 'net/http'
require 'uri'
uri = URI.parse("http://localhost:3030/dummy/create")
request = Net::HTTP::Post.new(uri)
request.content_type = "application/x-www-form-urlencoded"
# Rack::QueryParser::InvalidParameterError: Invalid encoding for parameter:
#G�bor
name = "Gábor".encode("windows-1252", "utf-8")
request.body = "last_name=#{name}&first_name=Sam&charset=windows-1252"
response = Net::HTTP.start(uri.hostname, uri.port, nil) do |http|
http.request(request)
end
# 400
pp response.code
而在服务器端,dummy#create
行动永远不会达到,它停止于
Started POST "/dummy/create" for 127.0.0.1 at 2021-02-06 17:14:12 +0100
ActionController::BadRequest (Invalid request parameters: Invalid encoding for parameter: G�bor):
actionpack (6.1.1) lib/action_dispatch/request/utils.rb:39:in `check_param_encoding'
actionpack (6.1.1) lib/action_dispatch/request/utils.rb:34:in `block in check_param_encoding'
actionpack (6.1.1) lib/action_dispatch/request/utils.rb:34:in `each_value'
actionpack (6.1.1) lib/action_dispatch/request/utils.rb:34:in `check_param_encoding'
actionpack (6.1.1) lib/action_dispatch/http/request.rb:403:in `block in POST'
rack (2.2.3) lib/rack/request.rb:69:in `fetch'
rack (2.2.3) lib/rack/request.rb:69:in `fetch_header'
actionpack (6.1.1) lib/action_dispatch/http/request.rb:398:in `POST'
actionpack (6.1.1) lib/action_dispatch/http/parameters.rb:55:in `parameters'
...
我发现我可以注册一个中间件来拦截这种调用,如中所述Rails/Rack:POST 数据的“ArgumentError:无效的 % 编码” https://stackoverflow.com/questions/15769681/rails-rack-argumenterror-invalid-encoding-for-post-data
然后中间件会检查 POST 中的“字符集”参数,这可能会起作用。然而,这有一个缺点,即它适用于所有呼叫,而不仅仅是dummy#create
端点。
由于这种行为是最近引入的(我假设是在 Rail 6.1 中),现在有更好的方法来处理这个问题吗?