为了回答这个问题,我们首先必须查看一些HTTP请求(仅是简单的
telnet“消息”;可以很容易地手动创建)。首先,提交普通的HTML会发生什么
<form>?该
POST请求看起来将与此非常相似(可能带有一些额外的参数,但是我们现在不必担心这一点):
POST /submit-form HTTP/1.1Host: localhostContent-Type: application/x-www-form-urlenpredContent-Length: 12name=JohnDoe
逐个字符地键入该字符(用
/sample-form任何形式操作的URL
替换URL,并
Host用您的IP或主机名替换该字符)将与您的浏览器发送的内容相同。要学习的重要内容是参数语法:
formname=formvalue。
Sinatra 使用此语法将
POST请求的内容解释为
params哈希!因此,与此基本不兼容的JSON请求将因此 不会
显示在
params哈希中。
但是,您在
before街区中所做的事情显示了正确的解决方案。虽然
params从上面将是
{'name' =>'JohnDoe'},request.body.read将返回原始主体,
name=JohnDoe。
知道了这一点,就可以理解为什么您的“
hacky”解决方案起作用了:
POST请求的原始主体由解释
JSON.parse,然后插入到空
params哈希中。看起来很笨拙的原因是因为
params在此示例中是不必要的中间人。以下应完成此工作:
post '/locations/new' do @json = JSON.parse(request.body.read) # @json now contains a hash of the submitted JSON contentend
但是,采用更好做法的解决方案要么仅在提供JSON内容时响应,要么在提交标准表单时做出不同响应。如上述示例HTTP
POST请求所示,HTML表单使用
application/x-www-form-urlenpredMIME类型标识,而JSON使用标识
application/json。



