尝试使用PATCH方法适用于AJAX但不适用于常规html表单

时间:2017-07-12 15:14:08

标签: php jquery altorouter

我目前正在尝试http://altorouter.com/,到目前为止它对我来说效果很好,除了我遇到的这个问题

我的路线设置如下:

$router->map( 'PATCH', '/admin/pages', 'pageController@update');

如果我使用以下jquery,路线可以完美运行:

$.ajax({
    type: "PATCH",
    url: "/admin/pages",
    data: {page_items:page_items, page_name: 'test_page'},
    success: function(returned_data)
    {
        console.log(returned_data);
    }
});

然而,无论我在HTML中添加什么,我都无法以一种接受为PATCH的方式提交常规表单:

<form action="/admin/pages" method="post">
    <input type="hidden" name="form_function" value="edit_theme">
    <input type="hidden" name="_METHOD" value="PATCH">
    <button type="submit">Save Page</button>
</button>

我尝试过“_METHOD”,“_ method”,“method”等等。这些都不起作用。

我也试过

method="PATCH"

但这只会导致它进行GET。

当我在目标页面上回显$ _SERVER ['REQUEST_METHOD']时,我得到ajax的“PATCH”,但只是表单的“POST”。希望有人可以提供帮助。

2 个答案:

答案 0 :(得分:0)

简而言之,你不能。

正如您在W3 Spec

中看到的那样

基于HTML的表单唯一有效的方法是“GET”和“POST”。

但是,如果您愿意,可以在服务器端解决此问题。这是一篇关于Laravel如何在这里做到的精彩文章:Theres no Put/Patch Delete Methods

该文章的快速代码片段:

<form method="POST" action="" accept-charset="UTF-8">
    <input name="_method" type="hidden" value="PUT">
</form>

<form method="POST" action="" accept-charset="UTF-8">
    <input name="_method" type="hidden" value="PUT">  
</form>
  

如果您不使用Laravel并且想要手动构建表单,则不能使用PUT / PATCH - 浏览器中的表单不支持这样的方法 - 它只是GET和POST。那么Laravel如何使用{{Form :: create(['method'=&gt;'PUT'])}}来实现它?   实际上,生成的HTML看起来像这样:

     

没错,Laravel构建一个名为_method和的隐藏字段   然后在表单提交时检查它,将其路由到正确的   控制器方法。

     

因此,如果您因任何原因需要自己构建FORM标记,   不要(同样适用于补丁和删除) - 它   只是不会工作。而是在必要时添加隐藏字段。

回到你的问题, Altorouter 。看来他们的文档是我能找到的最好的指南。https://recalll.co/app/?q=rest%20-%20PHP%20detecting%20request%20type%20(GET%2C%20POST%2C%20PUT%20or%20DELETE)%20-%20Stack%20Overflow在找到更好的路由器时可能值得你去,因为Alto似乎在3年左右没有更新。

答案 1 :(得分:0)

在挖掘代码后管理以找到可行的解决方案。 Altorouter的匹配方法实际上接受一个方法参数,似乎没有在任何地方记录。

以前我曾经拥有

$match = $router->match();

我现在有:

if(isset($_POST['_method']))
{
    $match = $router->match(null, $_POST['_method']);
}
else
{
    $match = $router->match();
}