【问题标题】:How can I accept (and parse) www-url-encoded data in a Ruby on Rails app?如何在 Ruby on Rails 应用程序中接受(并解析)www-url 编码的数据?
【发布时间】:2017-08-25 22:11:13
【问题描述】:

我从一个 JS 应用发送:

let config = {
  method: 'POST',
  headers: { 'Content-Type':'application/x-www-form-urlencoded' },
  body: `email=${creds.email}&password=${creds.password}`
}
fetch('http://localhost:3000/sessions', config)

在我的 Rails 控制器中:

 class SessionsController < ApplicationController
  def create
    @user = User.where(email: params[:email]) # this doesn't work!
  end
end

我收到 400 错误请求:

Started POST "/sessions" for 127.0.0.1 at 2017-08-25 23:56:56 +0200
Error occurred while parsing request parameters.
Contents:

email=hello&password=moto

ActionDispatch::Http::Parameters::ParseError
(743: unexpected token at 'email=hello&password=moto'):

任何人都可以了解如何处理来自 JS 的这些数据?

【问题讨论】:

  • 很难判断可能发生了什么,因为问题中的 JS 代码似乎与导致问题日志消息中显示的问题的 JS 代码不同。日志消息显示 POST 到 /sessions 路由的日志,但您的 JS 代码显示 POST 到 /sessions/create。日志消息还显示它正在接收email=hello&amp;password=moto,但您的 JS 代码是用于以username=hello&amp;password=moto 形式发送参数的 POST。
  • 鉴于问题中显示的 JS 代码与显示的服务器端日志消息的详细信息不匹配,可能希望使用stackoverflow.com/posts/45890012/edit 编辑/更新您的问题并发布实际的确切信息您正在测试请求的 JS 代码,以及当服务器接收到该请求时您在服务器端获得的实际确切日志消息。
  • @sideshowbarker 对不起!你说的对。不好的复制粘贴。我现在已经编辑了问题以完全匹配我在这里看到的内容。这是POST/sessions,发送/接收的数据是email=hello&amp;password=moto

标签: javascript ruby-on-rails redux form-data


【解决方案1】:

我相信,您应该添加 CSRF 令牌以绕过伪造保护并将此键值添加到您的标头中:

'X-CSRF-Token': document.querySelector("meta[name=csrf-token]").content

否则你可以使用捆绑的 rails-ujs 库,它已经包含了这个令牌:

Rails.ajax({
  type: "POST", 
  url: "http://localhost:3000/sessions/create",
  data: mydata,
  success: function(repsonse){...},
  error: function(repsonse){...}
})

【讨论】:

  • 谢谢! csrf-token 元标记到底应该包含什么?我的前端是完全分离的,所以看起来我必须手动将它放入我的 html 中。
  • csrf-token 由 Rails 根据请求生成,然后 Rails 将所有非 GET Ajax 请求与其进行比较。您可以在控制器中完全禁用伪造保护,但我认为这不是一个好主意。也许您可以将&lt;%= csrf_meta_tags %&gt; 传递给您的前端,然后在您的Ajax 请求中使用它?这是我从中获取的文档:http://guides.rubyonrails.org/security.html#csrf-countermeasures
  • 好的,现在可以了。但问题仍然悬而未决。我已更改标题以包含此内容:'Content-Type': 'application/json' 和要包含的正文:{"email":"${creds.email}","password":"${creds.password}"}。这(连同 Rails API 没有 csrf protection 的事实)让我认为这是阻止我将其编码为表单的其他原因。虽然,是否有可能只有某些(表单)POST 请求默认打开了该保护而其他(常规 POST 请求)没有? :|
  • @Claudio 是的,您可以指定要保护的特定操作。已发布
  • @7urkm3n 我的意思是这适用于 json。因此,它必须是 CSRF 以外的其他东西。 CSRF 关闭。这是一个没有 csrf 保护的 Rails API。以 json 格式发送数据有效。我想知道为什么它不适用于其他格式。
【解决方案2】:

是的,您可以为 csrf 保护指定特定操作。 -> DOC

class ApplicationController < ActionController::Base
  protect_from_forgery
end

class SessionsController < ApplicationController
  protect_from_forgery except: :create

  def create
    render plain: params
  end
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多