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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/50691938/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 17:47:25  来源:igfitidea点击:

PATCH and PUT Request Does not Working with form-data

phplaravelhttppostman

提问by notalentgeek

I am using Laravel to create a RESTFUL application and I test the application with Postman. Currently, there is an issue for PATCHor PUTif the data sent from Postman with form-data.

我正在使用 Laravel 创建一个 RESTFUL 应用程序,并使用 Postman 测试该应用程序。目前,邮递员发送的数据与表单数据存在问题,PATCH或者PUT是否存在问题。

// 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');
  • Using form-data, $request->all()will be okay for POST.
  • Using x-www-form-urlencoded, $request->all()will be okay for PATCH, PUT, and POST.
  • However, if I am sending PUTand PATCHwith form-data from Postman, the $request->all()will be empty (the parameters will not be sent to backend).
  • 使用表单数据,$request->all()对于POST.
  • 利用X WWW的形式了urlencoded,$request->all()会好起来的PATCHPUTPOST
  • 然而,如果我发送PUTPATCH从邮差表单数据时,$request->all()将是空的(参数将不会被发送到后端)。

Right now the solution is to use POSTfor updating a model. I want to know why PATCHand PUTis not working when sent with form-data from Postman.

现在的解决方案是POST用于更新模型。我想知道为什么PATCH并且PUT在从 Postman 发送表单数据时不起作用。

回答by Script47

This is a known issue and the workaround suggestion as per the following Github commentis that when sending a PATCH/ PUTrequests you should do the following:

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

You should send POST and set _method to PUT (same as sending forms) to make your files visible

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

So essentially you send a POST request with a parameter which sets the actual method and Laravel seems to understand that.

所以基本上你发送一个带有参数的 POST 请求,该参数设置了实际的方法,而 Laravel 似乎理解这一点。

As per the documentation:

根据文档

Since HTML forms can't make PUT, PATCH, or DELETErequests, you will need to add a hidden _methodfield to spoof these HTTP verbs. The @methodBlade directive can create this field for you:

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

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

    ...
</form> 

Alternatively, you can use the method_fieldhelper function to do the above:

或者,您可以使用method_field辅助函数执行上述操作:

The method_field function generates an HTML hidden input field containing the spoofed value of the form's HTTP verb. For example, using Blade syntax:

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

<form method="POST">
    {{ method_field('PUT') }}
</form>

回答by vietanhyt

Laravel PATCH and PUT method does not work with form-data, it's known issue of Symfony and even PHP (Google for that - Laravel use many Symfony foundation packages, include Request).

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

  1. If you do not need to pass file(s) via request, change form-datato rawwith json content-type. E.g: {"name":"changed"}. It will be read as php://inputand your code should work well ($request->all()is now ["name" => "changed]).

  2. If you need to pass file(s), in my opinion, DO NOTpass it within the REST API methods. You can write another method to do whatever you need with your file(s) (E.g: POST form-data-> upload file -> update db -> return a file path/url/even its base64 content), then you can use its output/result to continue with your patch/put method (rawwith json content-type). I always do that when I work with files in API.

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

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

Hope this help!

希望这有帮助!

回答by Caique Andrade

I learnt how to solve it here on this post and I'd like to share what did I do.

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

The following image is how I setup the Postman to send a HTTP POSTrequest and go into PUTRequest and make it receive my files.

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

I'm not sure whether it is the right way to do a RESTFul API. But it works fine

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

An example on Postman how to setup your HTTP Request

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

回答by Ridha Rezzag

so as everyone mentioned above and explained everything, but still i dont see the answer for cases when using a REST API so i fallowed @Caique Andrade answer and send a POST request and formed my URL link like this:

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

url = 'https://yourwebsite.com/api/v1/users/$id?_method=PUT';

$idis the variable id for the user.

$id是用户的变量 id。

?_method=PUTis added to the url POST request to spoof the request and it works

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

in my case i used Dart in flutter and sent a post request using Http package Laravel catches that POST request as a PUT request

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

回答by Julian Reschke

The form media types do not have any semantics defined for PATCH, so it's really a bad idea to use them (see https://www.rfc-editor.org/errata/eid3169).

表单媒体类型没有为 PATCH 定义任何语义,因此使用它们确实是一个坏主意(请参阅https://www.rfc-editor.org/errata/eid3169)。

For PUT, the expected behaviour would be to store just the form-encoded payload (in that format). Is this really what you want here?

对于 PUT,预期行为将仅存储表单编码的有效负载(以该格式)。这真的是你想要的吗?