问题 如何为Rails和GWT模拟PUT / DELETE?


我想使我的应用程序有点REST兼容。我在后端使用Rails GWT 在前端。我想做更新和删除。我意识到我可以做一些像mydomain.com/:id/delete(GET)这样的事情并完成同样的事情。但是,正如我之前所说,我希望有一个REST兼容的后端。因此,我想做mydomain.com/:id(DELETE)并让它隐式调用我的删除方法。

现在,我的理解是,如果浏览器(我的浏览器是GWT RequestBuilder)不支持DELETE / GET,Rails会以某种方式使用POST和其他一些url参数完成此任务。那么,我如何通过GWT RequestBuilder实现这一目标?


3496
2017-11-13 05:21


起源



答案:


Rails使用隐藏属性执行此操作。解决这个问题的最简单方法是创建一个新的rails应用程序,生成一个脚手架并在浏览器中查看HTML。

尝试这个:

rails jp
cd jp
./script/generate scaffold RequestBuilder name:string
rake db:migrate
./script/server 

然后导航到 HTTP://本地主机:3000 / request_builders,单击New并查看HTML。你会看到类似的东西:

<form action="/request_builders" class="new_request_builder" 
  id="new_request_builder" method="post">
  <div style="margin:0;padding:0">
    <input name="authenticity_token" type="hidden" value="e76..." />
  </div>

这是一个创建,方法是POST。输入名称,然后保存,然后编辑:

<form action="/request_builders/1" class="edit_request_builder" 
  id="edit_request_builder_1" method="post">
  <div style="margin:0;padding:0">
    <input name="_method" type="hidden" value="put" />
    <input name="authenticity_token" type="hidden" value="e76..." />
  </div>

当然,表单是通过POST发送的,但是Rails有一个隐藏字段来模拟PUT请求。同样的删除,但脚手架将使用一些Javascript:

var m = document.createElement('input'); 
m.setAttribute('type', 'hidden'); 
m.setAttribute('name', '_method'); 
m.setAttribute('value', 'delete');

要让这个与另一个前端一起工作,你必须同时:

  • 使用相同的样式URL,例如/ request_builders / 1(RESTful URL)
  • 包括隐藏字段(Rails技巧)

7
2017-11-13 07:46



遗憾的是,这不能被视为一个完整的解决方案,因为它仅适用于URL编码数据(表单),并且不适用于JSON或XML,这是使用GWT执行请求的更常见方式 - skrat


答案:


Rails使用隐藏属性执行此操作。解决这个问题的最简单方法是创建一个新的rails应用程序,生成一个脚手架并在浏览器中查看HTML。

尝试这个:

rails jp
cd jp
./script/generate scaffold RequestBuilder name:string
rake db:migrate
./script/server 

然后导航到 HTTP://本地主机:3000 / request_builders,单击New并查看HTML。你会看到类似的东西:

<form action="/request_builders" class="new_request_builder" 
  id="new_request_builder" method="post">
  <div style="margin:0;padding:0">
    <input name="authenticity_token" type="hidden" value="e76..." />
  </div>

这是一个创建,方法是POST。输入名称,然后保存,然后编辑:

<form action="/request_builders/1" class="edit_request_builder" 
  id="edit_request_builder_1" method="post">
  <div style="margin:0;padding:0">
    <input name="_method" type="hidden" value="put" />
    <input name="authenticity_token" type="hidden" value="e76..." />
  </div>

当然,表单是通过POST发送的,但是Rails有一个隐藏字段来模拟PUT请求。同样的删除,但脚手架将使用一些Javascript:

var m = document.createElement('input'); 
m.setAttribute('type', 'hidden'); 
m.setAttribute('name', '_method'); 
m.setAttribute('value', 'delete');

要让这个与另一个前端一起工作,你必须同时:

  • 使用相同的样式URL,例如/ request_builders / 1(RESTful URL)
  • 包括隐藏字段(Rails技巧)

7
2017-11-13 07:46



遗憾的是,这不能被视为一个完整的解决方案,因为它仅适用于URL编码数据(表单),并且不适用于JSON或XML,这是使用GWT执行请求的更常见方式 - skrat


就像@skrat所说的那样 _method=PUT 解决方法不适用于任何类型的身体 Content-Type 不是 x-www-form-urlencoded,例如XML或JSON。幸运的是,还有一个标题解决方法:

https://zcox.wordpress.com/2009/06/17/override-the-http-request-method-in-jersey/

因此,要更新REST资源,只需对其地址执行POST并添加标头 X-HTTP-Method-Override: PUT。 Rails会将此解释为地址的PUT。


6
2018-06-02 05:48