Как отправить delete запрос из браузера

Обновлено: 07.07.2024

Connector для Extjs, который я писал для своего RESTful приложения.

Ext. ns ( "SC.core" ) ;
SC. core . Connection = Ext. extend ( Ext. data . Connection , <
defaultHeaders : <
"Accept" : 'application/json'
> ,
method : "GET" ,
//
load : function ( url , params , success , failure , scope ) <
return this . req ( url , params , success , failure , scope , "GET" ) ;
> ,
post : function ( url , params , success , failure , scope ) <
if ( params )
params = Ext. util . JSON . encode ( params ) ;
return this . req ( url , params , success , failure , scope , "POST" , < "Content-Type" : "application/json" >) ;
> ,
update : function ( url , params , success , failure , scope ) <
if ( params )
params = Ext. util . JSON . encode ( params ) ;
return this . req ( url , params , success , failure , scope , "PUT" , < "Content-Type" : "application/json" >) ;
> ,
del : function ( url , params , success , failure , scope ) <
return this . req ( url , params , success , failure , scope , "DELETE" ) ;
> ,
upload : function ( url , params , files , success , failure , scope ) <
var f = document. createElement ( "form" ) ;
f. id = Ext. id ( ) ;

for ( var k in params ) <
var el = document. createElement ( "input" ) ;
el. name = k ;
el. value = Ext. util . JSON . encode ( params [ k ] ) ;
f. appendChild ( el ) ;
>

if ( files ) <
for ( var k in files ) <
if ( Ext. isElement ( files [ k ] ) ) <
var nn = files [ k ] . cloneNode ( true ) ;
nn. name = k ;
f. appendChild ( nn ) ;
>
>
>
document. body . appendChild ( f ) ;

return this . request ( <
url : url ,
method : "POST" ,
isUpload : true ,
debugUploads : true , //DEBUG MODE ONLY .
success : this . resultSuccess . createDelegate ( this , [ success , scope ] , true ) ,
failure : this . resultFailure . createDelegate ( this , [ failure , scope ] , true ) ,
// params: params,
form : f
> ) ;

console. log ( f ) ;
> ,
//private
req : function ( url , params , success , failure , scope , method , headers ) <
return this . request ( <
url : url ,
method : method ,
headers : headers ,
success : this . resultSuccess . createDelegate ( this , [ success , scope ] , true ) ,
failure : this . resultFailure . createDelegate ( this , [ failure , scope ] , true ) ,
params : params
> ) ;
> ,
//private
resultSuccess : function ( response , options , cb , scope ) <
if ( cb ) <
var res = null ;
try <
res = Ext. util . JSON . decode ( response. responseText ) ;
> catch ( e ) <
console. warn ( "decoding response faild" , response ) ;
>
cb. call ( scope || window , res , response. status , response ) ;
>
> ,

Есть ли какие-то функции в Chrome и / или Firefox, которых мне не хватает?

Я делаю приложение Chrome под названием Postman для подобных вещей. Все остальные расширения казались немного устаревшими, поэтому я сделал свои собственные. Он также имеет множество других функций, которые были полезны для документирования нашего собственного API здесь.

Postman теперь также имеет собственные приложения (т.е. автономные) для Windows, Mac и Linux! Сейчас предпочтительнее использовать собственные приложения, подробнее см. здесь.

CURL УДИВИТЕЛЬНЫЙ, чтобы делать то, что вы хотите! Это простой, но эффективный инструмент командной строки.

Команды тестирования реализации отдыха:

Firefox Dev Tools with button

POST request body highlighted

HTTPie screenshot

Если вы настаиваете на расширении браузера, то:

Chrome :

Firefox :

С формой, просто установите method на "post"

Т.е. создайте себе очень простую страницу для проверки действий публикации.

Вот расширение Advanced REST Client для Chrome.

У меня он отлично работает - помните, что вы все еще можете использовать с ним отладчик. Панель «Сеть» особенно полезна; он предоставит вам обработанные объекты JSON и страницы ошибок.

Для firefox есть также неплохое расширение RESTClient:

Может не иметь прямого отношения к браузерам, но fiddler - еще одно хорошее программное обеспечение.

Fiddler web debugger

Просто чтобы дать свои 2 цента за этот ответ, после повышения уровня Postman появились и другие клиенты, о которых стоит упомянуть здесь:

    : с приложением для ПК и плагин Chrome : ранее известная как Postwoman, и с также доступен плагин Chrome. Вы также можете заставить его работать локально с помощью Docker, если хотите подшутить : если вы используете Mac : уже упоминается как Chrome plugin, но стоит отметить, что в нем также есть настольное приложение : написан на java и с большим количеством функций тестирования. : еще один способ тестирования API. Он поставляется с интеграцией SOAP и имеет плагин Chrome доступен

Вы можете отправлять запросы прямо из браузера с помощью ReqBin. Никаких плагинов или настольных приложений не требуется.

Здесь есть хороший простой пример Fetch API здесь

Некоторые из преимуществ команды fetch действительно ценны: она проста, коротка, быстра, доступна и даже в качестве консольной команды она хранится на вашей консоли Chrome и может использоваться позже.

Простота нажатия F12, написания команды на вкладке консоли (или нажатия клавиши «вверх», если вы ее использовали раньше), а затем нажатия клавиши ввода, ожидания и возврата ответа - вот что делает ее действительно полезной для простых тестов на отправку запросов.

Конечно, основным недостатком здесь является то, что, в отличие от Postman, он не передает политику перекрестного происхождения, но все же я считаю его очень полезным для тестирования в локальной среде или других средах, где я могу включить CORS вручную.

From a user-, script-, or server- generated event, an HTTP/1.x msg is generated, and if HTTP/2 is in use, it is binary framed into an HTTP/2 stream, then sent.

Requests and responses share a common structure in HTTP

Стартовая строка

Заголовки

Существует множество заголовков запроса. Их можно разделить на несколько групп:

Последней частью запроса является его тело. Оно бывает не у всех запросов: запросы, собирающие (fetching) ресурсы, такие как GET , HEAD , DELETE , или OPTIONS , в нем обычно не нуждаются. Но некоторые запросы отправляют на сервер данные для обновления, как это часто бывает с запросами POST (содержащими данные HTML-форм).

Тела можно грубо разделить на две категории:

  • Одноресурсные тела (Single-resource bodies), состоящие из одного отдельного файла, определяемого двумя заголовками: Content-Type и Content-Length . ), состоящие из множества частей, каждая из которых содержит свой бит информации. Они обычно связаны с HTML-формами .

Строка статуса (Status line)

Заголовки

Example of headers in an HTTP response

Тела можно разделить на три категории:

  • Одноресурсные тела (Single-resource bodies), состоящие из отдельного файла известной длины, определяемые двумя заголовками: Content-Type и Content-Length .
  • Одноресурсные тела (Single-resource bodies), состоящие из отдельного файла неизвестной длины, разбитого на небольшие части (chunks) с заголовком Transfer-Encoding (en-US), значением которого является chunked . , состоящие из многокомпонентного тела, каждая часть которого содержит свой сегмент информации. Они относительно редки.

HTTP/2 modify the HTTP message to divide them in frames (part of a single stream), allowing for more optimization.

Заключение

Ну, мы дошли до того, что я потерял счет.

Говорят, PUT и DELETE . Я слышал только о POST и GET и никогда не видел, чтобы что-то вроде $_PUT или $_DELETE проходило мимо любого кода PHP, который я когда-либо просматривал.

Мой вопрос

Для чего нужны эти методы (PUT) и (DELETE), и если их можно использовать в PHP, как я могу это сделать.

Примечание. Я знаю, что на самом деле это не проблема, но я всегда хватаюсь за возможность научиться, если вижу ее, и очень хотел бы научиться использовать эти методы в PHP, если это возможно.

Что это за методы (PUT) и (DELETE) для .

Протокол в основном говорит следующее:

используйте GET , когда вам нужно получить доступ к ресурсу и получить данные , и вам не нужно изменять или изменять состояние этих данных.

используйте HEAD , когда вам нужно получить доступ к ресурсу и получить только заголовки из ответа , без каких-либо данных ресурса.

используйте PUT , когда вам нужно заменить состояние некоторых данных, уже существующих в этой системе.

используйте DELETE , когда вам нужно удалить ресурс (относительно отправленного вами URI) в этой системе.

используйте OPTIONS , когда вам нужно получить параметры связи от ресурса, поэтому для проверки разрешенных методов для этого ресурса . Бывший. мы используем его для запросов CORS и правил разрешений.

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

По сути, протокол - это набор правил, которые вы должны использовать в своем приложении для его соблюдения.

. и если их можно использовать в PHP, как бы я это сделал.

В приложении php вы можете узнать, какой метод использовался, просмотрев суперглобальный массив $_SERVER и проверив значение поля REQUEST_METHOD .

Итак, из вашего php-приложения вы теперь можете распознать, является ли это запросом DELETE или PUT, например. $_SERVER['REQUEST_METHOD'] === 'DELETE' или $_SERVER['REQUEST_METHOD'] === 'PUT' .

* Также имейте в виду, что некоторые приложения, работающие с браузерами, которые не поддерживают методы PUT или DELETE, используют следующий трюк, скрытое поле из html-формы с глаголом, указанным в его атрибуте value, например :

  • МЕТОД
  • Uri ресурса
  • Заголовки запроса, такие как User-Agent, Host, Content-Length и т. Д.
  • (Необязательный текст запроса)

Теперь, хотя вы можете получать данные из запросов POST и GET с соответствующими глобальными объектами ( $_GET , $_POST ), в случае запросов PUT и DELETE PHP не предоставляет эти глобальные объекты быстрого доступа; Но вы можете использовать значение $_SERVER['REQUEST_METHOD'] для проверки метода в запросе и, соответственно, обработки вашей логики.

Итак запрос PUT будет выглядеть так:

И вы можете получить доступ к этим данным в PHP, прочитав поток php://input , например. с чем-то вроде:

и запрос DELETE будет выглядеть так:

И снова вы можете построить свою логику после проверки метода:

Обратите внимание, что запрос DELETE не имеет тела, и обратите особое внимание на код состояния ответа (например, если вы получили запрос PUT и обновили этот ресурс без ошибок, вы должны вернуть статус 204 -No content- ) .

Что это за методы (PUT) и (DELETE)

Вкратце и несколько упрощая: PUT предназначен для загрузки файла по URL-адресу, а DELETE - для удаления файла по URL-адресу.

никогда не видел ничего подобного $_PUT или $_DELETE ни в одном PHP-коде, который я когда-либо просматривал

$_POST и $_GET ужасно названы суперглобалами. $_POST для данных, извлеченных из тела запроса. $_GET для данных, извлеченных из URL. Нет ничего, что строго связывало бы данные в любом из этих мест (особенно URL-адрес) с конкретным методом запроса.

Запросы DELETE заботятся только о пути URL, поэтому нет данных для анализа.

Запросы PUT обычно заботятся обо всем теле запроса (а не о его разобранной версии), к которому вы можете получить доступ с помощью file_get_contents('php://input'); .

если и возможно использовать их в PHP, как бы я это сделал.

Вам нужно будет сопоставить URL-адрес с PHP-скриптом (например, с помощью перезаписи URL-адреса), протестировать метод запроса, отработать какой URL-адрес вы на самом деле имел дело , а затем напишите код для выполнения соответствующего действия.

Чтобы добавить новый элемент:

Для обновления или редактирования:

Чтобы удалить существующий ресурс:

Есть много доступных библиотек, которые могут сделать это за вас.

Названия PHP $_GET и $_POST плохие. $_GET используется для доступа к значениям параметров строки запроса, а $_POST позволяет получить доступ к телу запроса.

Использование параметров строки запроса не ограничивается запросами GET, и другие типы запросов, помимо POST, могут иметь тело запроса.

Если вы хотите узнать, какой глагол используется для запроса страницы, используйте $_SERVER['REQUEST_METHOD'] .

Мечта, ради которой создавалась Сеть – это общее информационное пространство, в котором мы общаемся, делясь информацией. Его универсальность является его неотъемлемой частью: ссылка в гипертексте может вести куда угодно, будь то персональная, локальная или глобальная информация, черновик или выверенный текст.

Тим Бернес-Ли, Всемирная паутина: Очень короткая личная история

Протокол

Сервер отвечает по тому же соединению:

<!doctype html>
… остаток документа

Браузер берёт ту часть, что идёт за ответом после пустой строки и показывает её в виде HTML-документа.

Информация, отправленная клиентом, называется запросом. Он начинается со строки:

Первое слово – метод запроса. GET означает, что нам нужно получить определённый ресурс. Другие распространённые методы – DELETE для удаления, PUT для замещения и POST для отправки информации. Заметьте, что сервер не обязан выполнять каждый полученный запрос. Если вы выберете случайный сайт и скажете ему DELETE главную страницу – он, скорее всего, откажется.

Ответ сервера также начинается с версии протокола, за которой идёт статус ответа – сначала код из трёх цифр, затем строчка.

За первой строкой запроса или ответа может идти любое число строк заголовка. Это строки в виде “имя: значение”, которые обозначают дополнительную информацию о запросе или ответе. Эти заголовки были включены в пример:

Content-Length: 65585
Content-Type: text/html
Last-Modified: Wed, 09 Apr 2014 10:48:09 GMT

Тут определяется размер и тип документа, полученного в ответ. В данном случае это HTML-документ размером 65’585 байт. Также тут указано, когда документ был изменён последний раз.

По большей части клиент или сервер определяют, какие заголовки необходимо включать в запрос или ответ, хотя некоторые заголовки обязательны. К примеру, Host, обозначающий имя хоста, должен быть включён в запрос, потому что один сервер может обслуживать много имён хостов на одном ip-адресе, и без этого заголовка сервер не узнает, с каким хостом клиент пытается общаться.

Как мы видели в примере, браузер отправляет запрос, когда мы вводим URL в адресную строку. Когда в полученном HTML документе содержатся упоминания других файлов, такие, как картинки или файлы JavaScript, они тоже запрашиваются с сервера.

Веб-сайт средней руки легко может содержать от 10 до 200 ресурсов. Чтобы иметь возможность запросить их побыстрее, браузеры делают несколько запросов одновременно, а не ждут окончания запросов одного за другим. Такие документы всегда запрашиваются через запросы GET.

На страницах HTML могут быть формы, которые позволяют пользователям вписывать информацию и отправлять её на сервер. Вот пример формы:

Начало строки запроса обозначено знаком вопроса. После этого идут пары имён и значений, соответствующие атрибуту name полей формы и содержимому этих полей. Амперсанд (&) используется для их разделения.

В следующей главе мы вернёмся к формам и поговорим про то, как мы можем делать их при помощи JavaScript.

И всё же имя не полностью бессмысленное. Интерфейс позволяет разбирать вам ответы, как если бы это были документы XML. Смешивать две разные вещи (запрос и разбор ответа) в одну – это, конечно, отвратительный дизайн, но что поделаешь.

Отправка запроса

Можно получить из объекта response и другую информацию. Код статуса доступен в свойстве status, а текст статуса – в statusText. Заголовки можно прочесть из getResponseHeader.

Названия заголовков не чувствительны к регистру. Они обычно пишутся с заглавной буквы в начале каждого слова, например “Content-Type”, но “content-type” или “cOnTeNt-TyPe” будут описывать один и тот же заголовок.

Браузер сам добавит некоторые заголовки, такие, как “Host” и другие, которые нужны серверу, чтобы вычислить размер тела. Но вы можете добавлять свои собственные заголовки методом setRequestHeader. Это нужно для особых случаев и требует содействия сервера, к которому вы обращаетесь – он волен игнорировать заголовки, которые он не умеет обрабатывать.

Асинхронные запросы

В примере запрос был окончен, когда заканчивается вызов send. Это удобно потому, что свойства вроде responseText становятся доступными сразу. Но это значит, что программа наша будет ожидать, пока браузер и сервер общаются меж собой. При плохой связи, слабом сервере или большом файле это может занять длительное время. Это плохо ещё и потому, что никакие обработчики событий не сработают, пока программа находится в режиме ожидания – документ перестанет реагировать на действия пользователя.

Если третьим аргументом open мы передадим true, запрос будет асинхронным. Это значит, что при вызове send запрос ставится в очередь на отправку. Программа продолжает работать, а браузер позаботиться об отправке и получении данных в фоне.

Но пока запрос обрабатывается, мы не получим ответ. Нам нужен механизм оповещения о том, что данные поступили и готовы. Для этого нам нужно будет слушать событие “load”.

Так же, как вызов requestAnimationFrame в главе 15, этот код вынуждает нас использовать асинхронный стиль программирования, оборачивая в функцию тот код, который должен быть выполнен после запроса, и устраивая вызов этой функции в нужное время. Мы вернёмся к этому позже.

Получение данных XML

Мы можем получить такой файл следующим образом:

Документы XML можно использовать для обмена с сервером структурированной информацией. Их форма – вложенные теги – хорошо подходит для хранения большинства данных, ну или по крайней мере лучше, чем текстовые файлы. Интерфейс DOM неуклюж в плане извлечения информации, и XML документы получаются довольно многословными. Обычно лучше общаться при помощи данных в формате JSON, которые проще читать и писать – как программам, так и людям.

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

Абстрагируем запросы

В главе 10 в нашей реализации модульной системы AMD мы использовали гипотетическую функцию backgroundReadFile. Она принимала имя файла и функцию, и вызывала эту функцию после прочтения содержимого файла. Вот простая реализация этой функции:

Аргумент callback (обратный вызов) – термин, часто использующийся для описания подобных функций. Функция обратного вызова передаётся в другой код, чтобы он мог позвать нас обратно позже.

Основная проблема с приведённой обёрткой – обработка ошибок. Когда запрос возвращает код статуса, обозначающий ошибку (от 400 и выше), он ничего не делает. В некоторых случаях это нормально, но представьте, что мы поставили индикатор загрузки на странице, показывающий, что мы получаем информацию. Если запрос не удался, потому что сервер упал или соединение прервано, страница будет делать вид, что она чем-то занята. Пользователь подождёт немного, потом ему надоест и он решит, что сайт какой-то дурацкий.

Обработка ошибок в асинхронном коде ещё сложнее, чем в синхронном. Поскольку нам часто приходится отделять часть работы и размещать её в функции обратного вызова, область видимости блока try теряет смысл. В следующем коде исключение не будет поймано, потому что вызов backgroundReadFile возвращается сразу же. Затем управление уходит из блока try, и функция из него не будет вызвана.

Чтобы обрабатывать неудачные запросы, придётся передавать дополнительную функцию в нашу обёртку, и вызывать её в случае проблем. Другой вариант – использовать соглашение, что если запрос не удался, то в функцию обратного вызова передаётся дополнительный аргумент с описанием проблемы. Пример:

Мы добавили обработчик события error, который сработает при проблеме с вызовом. Также мы вызываем функцию обратного вызова с аргументом error, когда запрос завершается со статусом, говорящим об ошибке.

Код, использующий getURL, должен проверять не возвращена ли ошибка, и обрабатывать её, если она есть.

С исключениями это не помогает. Когда мы совершаем последовательно несколько асинхронных действий, исключение в любой точке цепочки в любом случае (если только вы не обернули каждый обработчик в свой блок try/catch) вывалится на верхнем уровне и прервёт всю цепочку.

Обещания

Тяжело писать асинхронный код для сложных проектов в виде простых обратных вызовов. Очень легко забыть проверку на ошибку или позволить неожиданному исключению резко прервать программу. Кроме того, организация правильной обработки ошибок и проход ошибки через несколько последовательных обратных вызовов очень утомительна.

Предпринималось множество попыток решить эту проблему дополнительными абстракциями. Одна из наиболее удачных попыток называется обещаниями (promises). Обещания оборачивают асинхронное действие в объект, который может передаваться и которому нужно сделать какие-то вещи, когда действие завершается или не удаётся. Такой интерфейс уже стал частью текущей версии JavaScript, а для старых версий его можно использовать в виде библиотеки.

Для создания объекта promises мы вызываем конструктор Promise, задавая ему функцию инициализации асинхронного действия. Конструктор вызывает эту функцию и передаёт ей два аргумента, которые сами также являются функциями. Первая должна вызываться в удачном случае, другая – в неудачном.

И вот наша обёртка для запросов GET, которая на этот раз возвращает обещание. Теперь мы просто назовём его get.

Заметьте, что интерфейс к самой функции упростился. Мы передаём ей URL, а она возвращает обещание. Оно работает как обработчик для выходных данных запроса. У него есть метод then, который вызывается с двумя функциями: одной для обработки успеха, другой – для неудачи.

Пока это всё ещё один из способов выразить то же, что мы уже сделали. Только когда у вас появляется цепь событий, становится видна заметная разница.

Вызов then производит новое обещание, чей результат (значение, передающееся в обработчики успешных результатов) зависит от значения, возвращаемого первой переданной нами в then функцией. Эта функция может вернуть ещё одно обещание, обозначая что проводится дополнительная асинхронная работа. В этом случае обещание, возвращаемое then само по себе будет ждать обещания, возвращённого функцией-обработчиком, и успех или неудача произойдут с таким же значением. Когда функция-обработчик возвращает значение, не являющееся обещанием, обещание, возвращаемое then, становится успешным, в качестве результата используя это значение.

Значит, вы можете использовать then для изменения результата обещания. К примеру, следующая функция возвращает обещание, чей результат – содержимое с данного URL, разобранное как JSON:

Последний вызов then не обозначил обработчик неудач. Это допустимо. Ошибка будет передана в обещание, возвращаемое через then, а ведь это нам и надо – getJSON не знает, что делать, когда что-то идёт не так, но есть надежда, что вызывающий её код это знает.

В качестве примера, показывающего использование обещаний, мы напишем программу, получающую число JSON-файлов с сервера, и показывающую во время исполнения запроса слово «загрузка». Файлы содержат информацию о людях и ссылки на другие файлы с информацией о других людях в свойствах типа отец, мать, супруг.

Можно представлять себе, что интерфейс обещаний – это отдельный язык для асинхронной обработки исполнения программы. Дополнительные вызовы методов и функций, которые нужны для его работы, придают коду несколько странный вид, но не настолько неудобный, как обработка всех ошибок вручную.

При создании системы, в которой программа на JavaScript в браузере (клиентская) общается с серверной программой, можно использовать несколько вариантов моделирования такого общения.

Общепринятый метод – удалённые вызовы процедур. В этой модели общение идёт по шаблону обычных вызовов функций, только функции эти выполняются на другом компьютере. Вызов заключается в создании запроса на сервер, в который входят имя функции и аргументы. Ответ на запрос включает возвращаемое значение.

Данные путешествуют по интернету по длинному и опасному пути. Чтобы добраться до пункта назначения, им надо попрыгать через всякие места, начиная от Wi-Fi сети кофейни до сетей, контролируемых разными организациями и государствами. В любой точке пути их могут прочитать или даже поменять.

Упражнения

Согласование содержания (content negotiation)

Наконец, попробуйте запросить содержимое типа application/rainbows+unicorns и посмотрите, что произойдёт.

Ожидание нескольких обещаний

У конструктора Promise есть метод all, который, получая массив обещаний, возвращает обещание, которое ждёт завершения всех указанных в массиве обещаний. Затем он выдаёт успешный результат и возвращает массив с результатами. Если какие-то из обещаний в массиве завершились неудачно, общее обещание также возвращает неудачу (со значением неудавшегося обещания из массива).

Попробуйте сделать что-либо подобное, написав функцию all.

Заметьте, что после завершения обещания (когда оно либо завершилось успешно, либо с ошибкой), оно не может заново выдать ошибку или успех, и дальнейшие вызовы функции игнорируются. Это может упростить обработку ошибок в вашем обещании.

Читайте также: