简体   繁体   English

尝试使用PATCH方法可与AJAX一起使用,但不能与常规html形式一起使用

[英]Trying to use PATCH method works with AJAX but not with a regular html form

I'm currently trying out http://altorouter.com/ and it's working well for me so far, except for this one issue I'm having 我目前正在尝试http://altorouter.com/ ,到目前为止对我来说效果很好,除了我遇到的这个问题

My route is set up like this: 我的路线设置如下:

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

If I use the following jquery, the route works perfectly: 如果我使用以下jquery,则路由可以正常工作:

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

However, no matter what I put in my HTML I can't get a regular form to submit in a way it accepts as PATCH: 但是,无论我在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>

I've tried "_METHOD", "_method", "method" etc. None of them work. 我已经尝试过“ _METHOD”,“ _ method”,“ method”等。它们都不起作用。

I've also tried 我也尝试过

method="PATCH"

but that only causes it to do a GET. 但这只会导致它执行GET。

When I echo the $_SERVER['REQUEST_METHOD'] on the target page I get "PATCH" for the ajax, but just "POST" for the form. 当我在目标页面上回显$ _SERVER ['REQUEST_METHOD']时,我得到的ajax为“ PATCH”,但表单的为“ POST”。 Hope someone can help. 希望有人能帮忙。

In short, you cannot. 简而言之,您不能。

As you'll see in the W3 Spec 正如您将在W3规范中看到的

The only valid methods for HTML based forms are "GET" and "POST". 基于HTML的表单的唯一有效方法是“ GET”和“ POST”。

However you can work around this if you wish, on the server side instead. 但是,您可以根据需要在服务器端解决此问题。 Theres a great article about how Laravel does it here: Theres no Put/Patch Delete Methods 这里有一篇关于Laravel如何做到的好文章: 没有删除/修补程序删除方法

A quick snippet of code from that article: 该文章的简短代码片段:

<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>

If you are not using Laravel and want to build a form manually, you cannot use PUT/PATCH – there's just no such methods supported by forms in browsers – it's only GET and POST. 如果您不使用Laravel并希望手动构建表单,则不能使用PUT / PATCH –浏览器中的表单不支持这种方法–只是GET和POST。 So how does Laravel make it work with {{ Form::create(['method' => 'PUT']) }}? 那么Laravel如何使其与{{Form :: create(['method'=>'PUT'])}}一起使用? Actually, under the hood the generated HTML looks like this: 实际上,在幕后生成的HTML看起来像这样:

That's right, Laravel constructs a hidden field with name _method and then checks it upon form submittion, routing it to the correct Controller method. 没错,Laravel构造了一个名为_method的隐藏字段,然后在提交表单时对其进行检查,并将其路由到正确的Controller方法。

So if for any reason you would need to build the FORM tag yourself, don't put (same applied to patch and delete) – it just won't work. 因此,如果出于任何原因您需要自己构建FORM标签,请不要放置(对修补程序和删除应用相同的标签)–它将不起作用。 Instead add hidden fields, if necessary. 如有必要,请添加隐藏字段。

So back to your issue, Altorouter . 回到您的问题, Altorouter It appears their documentation is rather lacing the best guide I can find for you is here https://recalll.co/app/?q=rest%20-%20PHP%20detecting%20request%20type%20(GET%2C%20POST%2C%20PUT%20or%20DELETE)%20-%20Stack%20Overflow it might be worth your while finding a better router, as Alto doesn't seem to have been updated in around 3 years. 看来他们的文档相当适合我在这里可以找到的最佳指南https://recalll.co/app/?q=rest%20-%20PHP%20detecting%20request%20type%20(GET%2C%20POST %2C%20PUT%20or%20DELETE)%20-%20Stack%20Overflow寻找更好的路由器可能是值得的,因为Alto似乎在3年左右没有更新。

Managed to find a working solution after digging around in the code. 在深入研究代码后设法找到一个可行的解决方案。 Altorouter's match method actually accepts a method parameter, which doesn't seem to be documented anywhere. Altorouter的match方法实际上接受一个方法参数,该参数似乎没有记录在任何地方。

Where I used to have 我曾经有过的地方

$match = $router->match();

I now have: 我现在有:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM