Запрос PATCH и PUT не работает с данными формы

Я использую 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');
  • Используя данные формы, $request->all() подойдет для POST.
  • Использование x-www-form-urlencoded, $request->all() подойдет для PATCH, PUT и POST.
  • Однако, если я отправляю PUT и PATCH с данными формы из Postman, $request->all() будет пустым (параметры не будут отправлены на бэкэнд).

Сейчас решение - использовать POST для обновления модели. Я хочу знать, почему PATCH и PUT не работают при отправке с данными формы из Postman.

Я не думаю, что это объясняет, почему form-data не работает с запросами PATCH и PUT.

notalentgeek 05.06.2018 06:20

Связанный: laracasts.com/discuss/channels/requests/…

Script47 05.06.2018 06:21

Больше по теме: github.com/laravel/framework/issues/13457

Script47 05.06.2018 06:21

Я видел это, до сих пор у него нет решения.

notalentgeek 05.06.2018 06:22

Вы, должно быть, неправильно прочитали, пожалуйста, проверьте мой ответ.

Script47 05.06.2018 06:23

Я не. Прочтите еще раз ... до сих пор не могу понять, почему ваши ссылки дают мне решение.

notalentgeek 05.06.2018 06:27

Это глупо. Я просто не могу работать с PHP.

Mattia Rasulo 20.04.2021 14:55
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
38
7
37 068
8

Ответы 8

Это известная проблема, и предлагаемое решение согласно следующему Github комментарий состоит в том, что при отправке запросов PATCH / PUT вы должны сделать следующее:

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

По сути, вы отправляете запрос POST с параметром, который устанавливает фактический метод, и Laravel, кажется, это понимает.

Согласно документация:

Since HTML forms can't make PUT, PATCH, or DELETE requests, you will need to add a hidden _method field to spoof these HTTP verbs. The @method Blade directive can create this field for you:

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

    ...
</form> 

В качестве альтернативы вы можете использовать вспомогательную функцию 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:

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

Я делаю RESTFUL приложение

notalentgeek 05.06.2018 06:28

Я не понимаю, как это повлияет на то, что это известная проблема? Вам нужно поступить иначе. Это так просто. Возможно, это не идеальный ответ, который вы хотели бы получить, но это правильный ответ.

Script47 05.06.2018 06:29

Метод Laravel PATCH и PUT не работает с form-data, это известная проблема Symfony и даже PHP (для этого Google - Laravel использует множество пакетов фундамента Symfony, включая Request).

  1. Если вам не нужно передавать файл (ы) через запрос, измените form-data на raw с типом содержимого json. Например: {"name":"changed"}. Он будет читаться как php://input, и ваш код должен работать нормально ($request->all() теперь ["name" => "changed]).

  2. Если вам нужно передать файл (ы), на мой взгляд, НЕ передает его в методах REST API. Вы можете написать другой метод, чтобы делать все, что вам нужно с вашим файлом (файлами) (например: POST form-data -> загрузить файл -> обновить базу данных -> вернуть путь к файлу / url / даже его содержимое base64), тогда вы можете использовать его вывод / result, чтобы продолжить использование вашего метода patch / put (raw с типом содержимого json). Я всегда так делаю, когда работаю с файлами в API.

Надеюсь на эту помощь!

Что, если я заменю PATCH или PUT на POST? Это хорошая практика?

notalentgeek 05.06.2018 08:05

Тебе решать. Однако мы должны использовать соглашение для нашего REST API. POST для создания нового, PATCH или PUT для обновления, DELETE для удаления ... Извините за поздний ответ. Очень поздно. : D

vietanhyt 06.02.2020 05:21

Типы носителей формы не имеют какой-либо семантики, определенной для PATCH, поэтому использовать их действительно плохая идея (см. https://www.rfc-editor.org/errata/eid3169).

Для PUT ожидаемым поведением будет сохранение только закодированной в форме полезной нагрузки (в этом формате). Вы действительно этого хотите?

Я узнал, как решить эту проблему, здесь, в этом посте, и хотел бы поделиться тем, что я сделал.

На следующем изображении показано, как я настраиваю Postman для отправки запроса HTTP POST, захожу в запрос СТАВИТЬ и заставляю его получать мои файлы.

Я не уверен, что это правильный способ сделать RESTFul API. Но работает нормально

An example on Postman how to setup your HTTP Request

в моем случае _method = PUT не работал, но _method = PATCH работает нормально

Ali_Hr 19.12.2020 12:45

так как все упомянули выше и все объяснили, но все же я не вижу ответа для случаев использования REST API, поэтому я последовал ответу @Caique Andrade и отправил запрос POST и сформировал свою URL-ссылку следующим образом:

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

$id - это идентификатор переменной для пользователя.

?_method=PUT добавлен в запрос POST url для подмены запроса, и он работает.

в моем случае я использовал Dart во флаттере и отправил почтовый запрос с использованием пакета Http Laravel перехватывает этот запрос POST как запрос PUT

Когда я использую этот метод, я получаю код 403. Любое предложение? Нужно будет что-то обновить на бэкэнде?

yoges nsamy 25.06.2020 12:43

вы, вероятно, не настроили его правильно, создайте вопрос и предоставьте свой код, чтобы мы могли помочь вам решить его, этот метод отлично работает в проектах laravel 7

Ridha Rezzag 25.06.2020 22:13

Как уже упоминалось, это не проблема Symfony (или laravel, или любого другого фреймворка), это ограничение PHP.

Изучив несколько хороших RFC для ядра php, команда разработчиков ядра, похоже, несколько сопротивляется реализации чего-либо, связанного с модернизацией обработки HTTP-запросов. Впервые об этой проблеме было сообщено в 2011 году, и это не похоже на то, чтобы иметь собственное решение.

Тем не менее, мне удалось найти это расширение PECL. Я не очень хорошо знаком с pecl и, похоже, не мог заставить его работать с грушей. но я использую CentOS и Remi PHP с пакетом yum.

Я запустил yum install php-pecl-apfd, и он буквально сразу устранил проблему (ну, мне пришлось перезапустить мои докер-контейнеры, но это было само собой разумеющимся).

То есть request->all() и files->get() снова начали работать с запросами PATCH и PUT с использованием multipart/form-data.

Я считаю, что есть и другие пакеты в различных вариантах Linux, и я уверен, что любой, кто больше знает о расширениях pear / pecl / general php, может без проблем запустить его на Windows или Mac.

Как говорит @DazBaldwin, это ограничение php, и его можно решить, установив расширение apfd. На окнах просто загрузите файл dll здесь в соответствии с настройками вашей системы и поместите php_apfd.dll в каталог путь к php / ext, наконец, поместите extension = apfd в файл php.ini.

это сработало для меня на окнах.

Вы можете использовать метод публикации. const form = новый просто добавьте form.append ('_ method', 'PATCH');

Введите коды в область исходного кода.

Istiak 30.01.2021 07:58

Расскажите подробнее

Caique Andrade 09.06.2021 19:55

Другие вопросы по теме