Отправить put запрос в браузере
Такой вызов означает, что удалённый клиент хотел бы сохранить файл под именем /path/filename.html в дереве каталогов вашего веб-сервера. Очевидно, что возможность клиента автоматически перезаписывать файлы веб-сервера при помощи Apache или PHP не является хорошим решением. Поэтому для того, чтобы обрабатывать такие запросы, вам необходимо указать веб-серверу PHP-скрипт, которому вы доверяете их обработку. В веб-сервере Apache вы можете сделать это, используя директиву Script. Как правило, эта директива расположена внутри блока <Directory> или же внутри блока <VirtualHost> . Сама запись выглядит следующим образом:
Это указывает веб-серверу Apache на необходимость перенаправлять все PUT-запросы, контекст которых совпадает с контекстом, в которым вы разместили эту строку, в файл put.php . Предполагается, что файлы с расширением .php обрабатываются, как PHP-скрипты, и что сам PHP установлен и работает. Ресурсом назначения для всех PUT-запросов на этот скрипт должен быть сам скрипт, а не имя файла, которое должен иметь загружаемый файл.
Внутри вашего файла put.php вы можете поместить что-нибудь похожее на следующий пример. Он скопирует содержимое загруженного файла в файл myputfile.ext на сервер. Возможно, вам понадобится осуществить несколько проверок и/или аутентифицировать пользователя перед выполнением копирования этого файла.
<?php
/* PUT данные приходят в потоке ввода stdin */
$putdata = fopen ( "php://input" , "r" );
/* Открываем файл на запись */
$fp = fopen ( "myputfile.ext" , "w" );
/* Читаем 1 KB данных за один раз
и пишем в файл */
while ( $data = fread ( $putdata , 1024 ))
fwrite ( $fp , $data );
/* Закрываем потоки */
fclose ( $fp );
fclose ( $putdata );
?>
User Contributed Notes 7 notes
Hello PHP World After many Hours of worryness :=)
I have found the Solution for Resume or Pause Uploads
In this Code Snippet it is the Server Side not Client on any Desktop Programm you must use byte ranges to calculate the uploaded bytes and missing of total bytes.
Here the PHP Code
try <
if (!( $putData = fopen ( "php://input" , "r" )))
throw new Exception ( "Can't get PUT data." );
// now the params can be used like any other variable
// see below after input has finished
$tot_write = 0 ;
$tmpFileName = "/var/dev/tmp/PUT_FILE" ;
// Create a temp file
if (! is_file ( $tmpFileName )) <
fclose ( fopen ( $tmpFileName , "x" )); //create the file and close it
// Open the file for writing
if (!( $fp = fopen ( $tmpFileName , "w" )))
throw new Exception ( "Can't write to tmp file" );
// Read the data a chunk at a time and write to the file
while ( $data = fread ( $putData , $CHUNK )) <
$chunk_read = strlen ( $data );
if (( $block_write = fwrite ( $fp , $data )) != $chunk_read )
throw new Exception ( "Can't write more to tmp file" );
if (! fclose ( $fp ))
throw new Exception ( "Can't close tmp file" );
unset( $putData );
> else <
// Open the file for writing
if (!( $fp = fopen ( $tmpFileName , "a" )))
throw new Exception ( "Can't write to tmp file" );
// Read the data a chunk at a time and write to the file
while ( $data = fread ( $putData , $CHUNK )) <
$chunk_read = strlen ( $data );
if (( $block_write = fwrite ( $fp , $data )) != $chunk_read )
throw new Exception ( "Can't write more to tmp file" );
if (! fclose ( $fp ))
throw new Exception ( "Can't close tmp file" );
// Check file length and MD5
if ( $tot_write != $file_size )
throw new Exception ( "Wrong file size" );
$md5_arr = explode ( ' ' , exec ( "md5sum $tmpFileName " ));
$md5 = $md5sum_arr [ 0 ];
if ( $md5 != $md5sum )
throw new Exception ( "Wrong md5" );
> catch ( Exception $e ) <
echo '' , $e -> getMessage (), "\n" ;
>
?>
GET запрос при помощи cURL
cURL - мощный инструмент для отправки запросов. Только взгляните сколько он всего умеет.
Все настройки, которые вы можете найти по этой ссылке. Там вы найдете опции, которые мы будем устанавливать функцией curl_setopt, в дальнейших примерах.
Пример простого GET запроса при помощи cURL:
В итоге, переменная $result снова содержит html код страницы этого сайта.
- CURLOPT_VERBOSE - установлена в true для вывода дополнительной информации. Записывает вывод в поток STDERR, или файл, указанный параметром CURLOPT_STDERR.
- CURLOPT_RETURNTRANSFER - установлена в true, для того чтобы вернуть ответ сервера. Если вам ответ сервера не нужен, то можете убрать эту опцию.
Если в результате сервер вернет нам редирект, то мы по нему автоматически не перейдем. А иногда это бывает полезно. Чтобы cURL автоматически шел по редиректу нужно установить опцию CURLOPT_FOLLOWLOCATION.
С установленной опцией скрипт автоматически перейдет по вернувшемуся редиректу и вернет ответ уже с итоговой страницы.
POST запрос при помощи cURL
Отлично, с GET и POST запросами в cURL мы немного освоились. Теперь разберемся с заголовками, которые мы можем отсылать в запросе.
cURL: POST запрос в формате JSON
Отличия конфигурации JSON запроса от обычного POST запроса заключается в том, что мы кодируем поля при помощи json_encode() И добавляем заголовок Content-Type: application/json
cURL: GET запрос в формате JSON
GET запрос в формате JSON отправляется так же как и POST запрос, просто нужно CURLOPT_CUSTOMREQUEST установить в 'GET'
А в остальном код идентичен предыдущему примеру. Хотя, надо признать, GET запросы с телом - это нонсенс. Обычно для этих целей используется POST, PUT или PATCH, но был у меня один случай. Поэтому вот GET запрос в формате JSON.
Стоп, Дмитрий, прекрати выдумывать виды запросов!
Это делается по тому же принципу, как и CURLOPT_POST. Но что делать с остальным зоопарком запросов? Разве у cURL есть CURLOPT_DELETE или CURLOPT_HEAD? Нет.
Для того, чтобы отправлять другие виды запросов есть другая опция: CURLOPT_CUSTOMREQUEST
Вместо строки curl_setopt($curl, CURLOPT_POST, true); мы явно задаем имя запроса опцией CURLOPT_CUSTOMREQUEST:
Замечание: Не используйте эту возможность пока не убедитесь, что сервер поддерживает данный тип запроса.
Как получить заголовки ответа
В предыдущем примере мы научились посылать заголовки. Самый правильный способ принять заголовки:
Иногда можно встретить другой вариант получения заголовков ответа. К сожалению, они не совсем правильные и могут работать некорректно в некоторых случаях.
Рассмотрим такой пример:
Мы сначала определяем размер заголовка, с помощью CURLINFO_HEADER_SIZE затем вырезаем его из ответа. К сожалению, это может не срабатывать, когда используется прокси или в некоторых случаях редиректа.
Скачивание больших файлов с помощью cURL
Для того, чтобы скачать большой файл пригодится этот способ:
Обратите внимание, если вы будете использовать file_get_contents для скачивания файлов, то файл сначала загружается в оперативную память, а потом сохраняется на диск. Поэтому если файл действительно большой, то скорее всего вашему серверу не хватит памяти. Также к памяти будет требователен следующий код:
Здесь мы скачиваем файл при помощи cURL в оперативную память, а затем сохраняем его на диск. Не смотря на то, что этот способ не годится для скачивания больших файлов, с помощью него можно вполне сохранить простую веб страницу.
Параллельные cURL запросы в PHP
Для чего могут потребоваться многопоточные запросы? Например у нас есть много URL адресов:
И если мы будем по очереди отправлять запросы, то второй запрос начнется только после того, как закончился первый и так далее, а это существенно увеличивает время работы скрипта.
Выглядит это так:
Теперь в $results у нас содержится массив, где ключи - это url адреса, а значения - результаты запросов. Однако запросы выполняются долго. Но мы можем это ускорить.
Как выполнить 3 запроса одновременно? В этом нам поможет curl_multi_
Такие параллельные запросы выполняются значительно быстрее чем поочередные.
cURL запросы с сохранением и загрузкой cookie из файла
cURL позволяет нам установить cookie при передачи запросов, а также автоматически принимать и устанавливать cookie, которые нам возвращает сервер, сохраняя их между запросами.
Давайте рассмотрим такой пример:
Теперь cookie у нас хранятся в файле cookie.txt в директории со скриптом (если вы ничего не меняли). Если мы совершаем повторные запросы, то cURL автоматически берет и отправляет cookie на сервер, как и обычный браузер. Таким образом мы можем авторизироваться на сайте и сохранить сеанс между запросами.
Передача cookie без файлов
Иммитация браузера с помощью cURL
Иногда сайт, к которому мы обращаемся может фильтровать запросы, защищаясь от парсинга. Если для этого используются упрощенные способы защиты, например проверка User-Agent, то мы можем легко притвориться, что являемся реальным польователем, который взаимодействует с сайтом через браузер, мы можем послать заголовки и cookie, которые обычно посылает браузер.
В данном примере установлены заголовки, которые посылает Chrome.
В простых ситуациях этого хватает. Но если используется защита при помощи javascript или что-то более продвинутое, то здесь cURL бессилен, и следует использовать либо BAS либо Zennoposter. Либо если вы хотите попытать счастье с PHP, то Selenium.
Не используйте эти знания в противоправных целях.
cURL запросы через прокси
Простой пример для отправки запросов через proxy. Если ваш прокси предполагает авторизацию, то раскомментируйте соответствующие строчки.
Отправка файлов
Авторизация с помощью cURL
OAuth авторизация
Авторизация через форму
Допустим на сайте есть такая форма:
Тогда наш cURL запрос должен быть сформирован так:
Автоматическое построение запросов
Перевод консольной команды curl в PHP
Так вы можете создать простые запросы на cURL в PHP не создавая их вручную.
Лайфхак
В консоли браузера, во вкладке сеть, вы можете кликнуть правой кнопкой мыши и скопировать любой запрос в виде команды cURL, а потом с помощью сервиса curl-to-php перевести запрос в PHP. Теперь вы вообще можете сконвертировать в cURL абсолютно любой запрос, который посылает ваш браузер.
Как работать с cURL гораздо проще
Вы можете спросить: почему у cURL такие кривые и страшные методы? У вас может возникнуть желание взять и создать обертку для работы с cURL, чтобы вы могли не писать каждый раз большие куски некрасивого кода, а писать все проще, например так:
Просто установите ее при помощи: composer require php-curl-class/php-curl-class и не работайте с кривыми кусками кода, которые таковы вероятно потому, что cURL изначально консольное приложение.
POST и GET запросы без cURL
Теперь у нас в переменной $result записан весь html код главной страницы этого сайта. Мы совершили GET запрос, а html код - это ответ на него.
Как видите file_get_contents - полезная функция, которая не только позволяет читать файлы на нашем сервере, но еще и отправлять запросы.
Спецификация HTTP 1.1 гласит, что PUT идемпотентен. Это значит, что клиент может выполнить множество PUT запросов по одному URI и это не приведет к созданию записей дубликатов. Операции присвоения — хороший пример идемпотентной операции
String userId = this.request["USER_ID"];
Даже если эту операцию выполнить дважды или трижды, никакого вреда не будет (кроме лишних тактов процессора). POST же с другой стороны не идемпотентен. Это что-то вроде инкремента. Вам следует использовать POST или PUT с учетом того является ли выполняемое действие идемпотентным или нет. Говоря языком программистов, если клиент знает URL объекта, который нужно создать, используйте PUT. Если клиент знает URL метода/класса создающего нужный объект, используйте POST.
Здесь приведен "хороший пример идемпотентной операции String userId = this.request["USER_ID"];". В чем пример хороший не пойму? Какой вред может быть от этой операции если мы используем POST а не PUT? Был бы очень признателен, если бы мне дали простой пример, где лучше применять PUT и почему.
Например огромное число сервисов для загрузки файлов использует PUT. Чем это оправдано?
Меня интересует в частности загрузка файлов.
1,753 1 1 золотой знак 16 16 серебряных знаков 31 31 бронзовый знак Словоблудие это все. С т.з. реальной программы, как сделал, так и будет. В любом случае (и PUT и POST) программа на сервере получает (в принципе) URL, заголовки и данные. И отправляет назад код результата, заголовки и данные. Так это же противоречит принципу бритвы Окамы "не наплоди лишних сущностей"Разница между PUT и POST - это вопрос семантики. Коль скоро для операций используются разные глаголы, то и смысл у них должен быть разным.
Представьте, что ваш сервис оперирует понятиями блокнот (notebook) и запись (post). Один блокнот может содержать множество записей.
Для добавления новой записи в блокнот c идентификатором id вы будете использовать метод POST с URL mydomain/notebooks/id/. Ваш сервис, ориентируясь на метод POST, сам присвоит нужный идентификатор записи, добавит ее в блокнот и вернет вам URL созданной записи (для доступа к записи по GET или для удаления по DELETE). При этом хорошо бы вернуть клиенту URL созданной записи.
Допустим, запись с идентификатором post-id уже создана и доступна по URL mydomain/notebooks/id/posts/post-id. Но клиент (владелец записи) исправил в ней ошибку и хочет перезаписать ее. Для этого он использует метод PUT с URL mydomain/notebooks/id/posts/post-id и передает обновленную запись в теле запроса. Ваш сервис, ориентируясь на метод PUT удаляет старую запись и записывает новую, при этом она доступна по тому же URL.
Конечно, никто не мешает вам всегда использовать метод POST (например HTML 4 позволял использовать только методы GET и POST). Но все же стоит придерживаться рекомендаций в целях единообразной трактовки методов всеми разработчиками.
UPD: Вспомнил еще кое-что. Рекомендуется использоваться метод POST для создания подчиненного ресурса (дочернего по отношению к другому ресурсу; пример блокнота и записи как раз очень подходит).
Есть ли какие-то функции в Chrome и / или Firefox, которых мне не хватает?
Я делаю приложение Chrome под названием Postman для подобных вещей. Все остальные расширения казались немного устаревшими, поэтому я сделал свои собственные. Он также имеет множество других функций, которые были полезны для документирования нашего собственного API здесь.
Postman теперь также имеет собственные приложения (т.е. автономные) для Windows, Mac и Linux! Сейчас предпочтительнее использовать собственные приложения, подробнее см. здесь.
CURL УДИВИТЕЛЬНЫЙ, чтобы делать то, что вы хотите! Это простой, но эффективный инструмент командной строки.
Команды тестирования реализации отдыха:
Если вы настаиваете на расширении браузера, то:
Chrome :
Firefox :
С формой, просто установите method на "post"
Т.е. создайте себе очень простую страницу для проверки действий публикации.
Вот расширение Advanced REST Client для Chrome.
У меня он отлично работает - помните, что вы все еще можете использовать с ним отладчик. Панель «Сеть» особенно полезна; он предоставит вам обработанные объекты JSON и страницы ошибок.
Для firefox есть также неплохое расширение RESTClient:
Может не иметь прямого отношения к браузерам, но fiddler - еще одно хорошее программное обеспечение.
Просто чтобы дать свои 2 цента за этот ответ, после повышения уровня Postman появились и другие клиенты, о которых стоит упомянуть здесь:
-
: с приложением для ПК и плагин Chrome : ранее известная как Postwoman, и с также доступен плагин Chrome. Вы также можете заставить его работать локально с помощью Docker, если хотите подшутить : если вы используете Mac : уже упоминается как Chrome plugin, но стоит отметить, что в нем также есть настольное приложение : написан на java и с большим количеством функций тестирования. : еще один способ тестирования API. Он поставляется с интеграцией SOAP и имеет плагин Chrome доступен
Вы можете отправлять запросы прямо из браузера с помощью ReqBin. Никаких плагинов или настольных приложений не требуется.
Здесь есть хороший простой пример Fetch API здесь
Некоторые из преимуществ команды fetch действительно ценны: она проста, коротка, быстра, доступна и даже в качестве консольной команды она хранится на вашей консоли Chrome и может использоваться позже.
Простота нажатия F12, написания команды на вкладке консоли (или нажатия клавиши «вверх», если вы ее использовали раньше), а затем нажатия клавиши ввода, ожидания и возврата ответа - вот что делает ее действительно полезной для простых тестов на отправку запросов.
Конечно, основным недостатком здесь является то, что, в отличие от Postman, он не передает политику перекрестного происхождения, но все же я считаю его очень полезным для тестирования в локальной среде или других средах, где я могу включить CORS вручную.
Читайте также: