PATCH和PUT请求不适用于表单数据

not*_*eek 5 php http laravel postman

我正在使用Laravel创建RESTFUL应用程序,并使用Postman测试该应用程序。当前,PATCH或者PUT从Postman发送的带有表单数据的数据是否存在问题。

// Parameter `{testimonial}` will be sent to backend.
Route::post  ('testimonials/{testimonial}', 'TestimonialController@update');

// Parameter `{testimonial}` will not be sent to backend (`$request->all()` will be empty) if sent from Postman with form-data.
Route::patch ('testimonials/{testimonial}', 'TestimonialController@update');
Route::put   ('testimonials/{testimonial}', 'TestimonialController@update');
Run Code Online (Sandbox Code Playgroud)
  • 使用form-data $request->all()可以POST
  • 利用X WWW的形式了urlencoded,$request->all()会好起来的PATCHPUTPOST
  • 但是,如果我从Postman 发送PUTPATCH使用表单数据,则$request->all()它将为空(参数将不会发送到后端)。

现在,解决方案是POST用于更新模型。我想知道为什么PATCHPUTPostman的表单数据一起发送时不起作用。

小智 42

我在这篇文章中学会了如何解决它,我想分享我做了什么。

下图是我如何设置 Postman 以发送HTTP POST请求并进入PUT请求并使其接收我的文件。

我不确定这是否是执行 RESTFul API 的正确方法。但它工作正常

Postman 的示例如何设置您的 HTTP 请求

  • 就我而言 _method=PUT 不起作用,但 _method=PATCH 工作正常 (2认同)

Scr*_*t47 12

这是一个已知问题,根据以下Github 注释的解决方法建议是,在发送PATCH/ PUT请求时,您应该执行以下操作:

您应该发送POST并将_method设置为PUT(与发送表单相同)以使文件可见

因此,从本质上讲,您发送的POST请求带有用于设置实际方法的参数,Laravel似乎理解这一点。

根据文档

由于HTML表单无法发出PUTPATCHDELETE请求,因此您需要添加一个隐藏 _method字段来欺骗这些HTTP动词。该@method刀片指令可以为您创建此字段:

<form action="/foo/bar" method="POST">
    @method('PUT')

    ...
</form> 
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用method_field助手功能执行上述操作:

method_field函数生成一个HTML隐藏的输入字段,其中包含表单的HTTP动词的欺骗值。例如,使用Blade语法:

<form method="POST">
    {{ method_field('PUT') }}
</form>
Run Code Online (Sandbox Code Playgroud)

  • 我正在制作 RESTFUL 应用程序 (3认同)

Rid*_*zag 9

所以正如上面每个人提到的并解释了一切,但我仍然没有看到使用 REST API 时案例的答案,所以我放弃了@Caique Andrade 的回答并发送了一个 POST 请求并形成了我的 URL 链接,如下所示:

url = 'https://yourwebsite.com/api/v1/users/$id?_method=PUT';
Run Code Online (Sandbox Code Playgroud)

$id 是用户的变量 id。

?_method=PUT 被添加到 url POST 请求以欺骗请求并且它工作

就我而言,我在 Flutter 中使用了 Dart 并使用 Http 包发送了一个 post 请求,Laravel 将该 POST 请求作为 PUT 请求捕获


vie*_*hyt 8

Laravel PATCH 和 PUT 方法不适用于form-data,这是 Symfony 甚至 PHP 的已知问题(谷歌为此 - Laravel 使用许多 Symfony 基础包,包括请求)。

  1. 如果您不需要通过请求传递文件,请更改form-datarawjson content-type。例如:{"name":"changed"}。它将被读取,php://input并且您的代码应该可以正常工作($request->all()现在是["name" => "changed])。

  2. 如果您需要传递文件,在我看来,不要在 REST API 方法中传递它。您可以编写另一种方法来对文件执行任何您需要的操作(例如:POST form-data-> 上传文件-> 更新数据库-> 返回文件路径/url/甚至其 base64 内容),然后您可以使用其输出/结果继续您的补丁/放置方法(raw使用 json 内容类型)。当我在 API 中处理文件时,我总是这样做。

希望这有帮助!


Car*_*les 5

InertiaJS解决方案

我有同样的问题。当没有发送文件时,一切正常,但是当我发送文件时,没有任何字段将其发送到后端。

这似乎是 PHP 的限制,无法通过 put 接收文件,如之前所述。

因此,对于使用 InertiaJS 的用户,您需要进行post调用(而不是put调用)并将其添加_method: "put"到惯性表单中,如下所示:

updateForm: this.$inertia.form({
            _method: "put",
            "other fields"
        }),
Run Code Online (Sandbox Code Playgroud)

您的控制器将像PUT调用一样理解它,但后端可以访问该文件。

来源: https: //inertiajs.com/manual-visits#method