【问题标题】:Trying to use PATCH method works with AJAX but not with a regular html form尝试使用 PATCH 方法适用于 AJAX,但不适用于常规 html 表单
【发布时间】:2017-12-17 02:43:49
【问题描述】:

我目前正在试用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”。希望有人能帮忙。

【问题讨论】:

    标签: php jquery altorouter


    【解决方案1】:

    简而言之,你不能。

    正如您将在 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’ => ‘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 年内没有更新。

    【讨论】:

    • 感谢您的帮助,不过我找到了适合我的解决方案。
    【解决方案2】:

    在深入研究代码后设法找到了可行的解决方案。 Altorouter 的 match 方法实际上接受一个方法参数,这似乎没有在任何地方记录。

    我曾经拥有的地方

    $match = $router->match();
    

    我现在有:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-16
      • 1970-01-01
      • 2019-01-14
      • 1970-01-01
      • 2019-01-09
      • 1970-01-01
      • 2019-08-31
      相关资源
      最近更新 更多