Вопрос по протоколу HTTP. Методы PUT и POST

Всем привет.

Опять буду мучить сообщество глупыми вопросами…


Ситуация следующая: МК общается с компом через web-страничку. Нужно передать файлик с компа на МК. Есть такие методы в HTTP: PUT и POST. Почитал про них в инете — в общих чертах описано что их можно использовать для передачи файлов. Но вот конкретики никакой. Отсюда вытекает вопрос знатокам:
1. Какой метод лучше использовать PUT, POST, или может есть еще более правильный вариант?
2. Как правильно данный метод реализовать (код не нужно, достаточно словесного описания)?
3. Возможно ли простыми методами выбирать файл в дириктории компа (выпадающие меню и прочие виды) или забить на это и указать фиксированный путь (вводить путь вручную в форме)? Ну и если можно — то как это сделать?

Спасибо.
  • 0
  • 05 апреля 2012, 14:12
  • Ultrin

Комментарии (37)

RSS свернуть / развернуть
Если в браузере, то PUT там просто нет. А дальше — www.w3.org/TR/html401/interact/forms.html
0
  • avatar
  • atd
  • 05 апреля 2012, 14:25
Да, как самай простой вариант — найти сайт с аплоадом файлов (через форму, а не всякий флэш) и посмотреть как это у них сделано.
0
Может я конечно туплю, но не нашел там ничего по существу вопроса, акромя формы запроса имени файла «file select». С ней конечно поэкспериментирую, чего получится…
0
если вдумчиво прочитать, то там будет всё что надо, и как форму сделать, и что там в МК придёт.

а вообще, коммент ниже кратко описал всё, что вам может потребоваться.
0
Что такое PUT я уже забыл. Так что про POST.
С различными новыми методами формирования пост-запроса тоже не знаком, только с отсылкой формы через POST.
Пункт 3 в этом случае без вариантов — только элемент для указания файла (type=«file»).
В случае запроса POST данные отсылаются в теле запроса, т.е:
POST /path HTTP/1.1
<Headers>
<пустая строка>
<Данные>

Данные как правило кодируются как multipart/form-data, в этом случае в заголовках обязательно будет пункт
Content-Type=multipart/form-data; boundary=----------wptznu3Y7JgMJ6wVoXY9K4

Бессмысленный набор символов после «boundary=» — разделитель, его необходимо из заголовка извлечь. Затем по этим разделителям поток данных разбивается на части (каждый разделитель — в отдельной строке, т.е. перед ним и после него обязательно CRLF, относящиеся к нему же, из исключений только разделители в первой и последней строках). Каждая часть имеет формат, похожий на запрос — несколько заголовков, пустая строка и собственно данные.
Выглядит это примерно так:
------------wptznu3Y7JgMJ6wVoXY9K4
Content-Disposition: form-data; name="fileup"; filename="sqlite.sql"
Content-Type: application/octet-stream

CREATE TABLE IF NOT EXISTS AREA (
  KEY_AREA BIGINT(10) NOT NULL PRIMARY KEY,
  TITLE VARCHAR(200) NOT NULL DEFAULT '',
  UNIQUE (TITLE)
);
------------wptznu3Y7JgMJ6wVoXY9K4
Content-Disposition: form-data; name="some"

dfgdgsdg
------------wptznu3Y7JgMJ6wVoXY9K4--
+2
  • avatar
  • Vga
  • 05 апреля 2012, 14:33
Во, пока я писал про сам html, ты уже успел написать про то, что на МК придет, да, именно это и придет :)
Причем name=«fileup» и name=«some» это, емнип, как раз те самые атрибуты name у тегов /> — вот тут как раз name=«myfile».
Ну и стоит еще отметить, что там файл вроде кодируется, или нет? Чем-то вроде base64? Или я вру?.. Если файл не текстовый, а бинарный…
0
Блин, тег съелся :)
… те самые атрибуты name у тегов " input type=«file» "...
0
Причем name=«fileup» и name=«some» это, емнип, как раз те самые атрибуты name у тегов
Они самые.
Ну и стоит еще отметить, что там файл вроде кодируется, или нет? Чем-то вроде base64?
Нет, HTTP передает бинарные данные без кодирования. Единственное требование — в данных не должен встречаться разделитель, но это уже забота браузера.
-1
Хм, да, наверное про base64 это мне с почты и писем стукнуло, в теле писем файло в base64…
0
Может и base64 и вообще чёрти-знает-что. всё зависит от enctype формы, и если это m/f-d, то от content-type каждого парта.

но обычно для файлов используется multipart, и внутри octet-stream
+1
пардон, для партов — не content-type, а content-transfer-encoding. но лучше не заморачиваться, и сделать как у всех )
0
Вообще да, надо смотреть Content-Type в хедере соответствующего куска и декодировать соответственно)
Правда в условиях МК (если это не кортекс с полметром флеша) памяти хватит разве что на проверку Content-Type на соответствие «application/octet-stream» и отправку «Используйте другой браузер», если не совпало)
0
к счастью у меня кортекс. Поэкспериментируем — увидим…
0
я бы даже на кортексе не заморачивался, а проверял только на наиболее популярный вариант.

даже если у вас полметра флэша и 64к рамы, то думаю не стоит их все тратить на поддержку редкоиспользуемых функций
0
Ну это понятно. Я даже парсинг делаю не полностью а по некоторым ключевым точкам, чтоб не загромождать код…
0
Как оно должно прийти на МК, понятия не имею, но вот на стороне ПК простейшая страничка:
<html>
<head>
<title>Документ Без Имени</title>
</head>
<body>
  <form id="myform" name="myform" enctype="multipart/form-data" method="post" action="script_kotorii_poluchit_dannie_o_faile.html">
    <input type="file" name="myfile" />
    <input type="submit" name="submit" value="Отправить" />
  </form>
</body>
</html>

Если вы такую страничку с вашего МК выдадите в браузер, то в нем будет форма для загрузки файла, с выбором файла и кнопкой Отправить.
После нажатия на кнопку обычно происходит загрузка файла на сервер, при этом файл обычно попадает на сервере в специальную папку для хранения временных файлов, а скрипт (php или другого рода страничка), который указан в атрибуте «action» как раз и получает массив с данными об этом файле, который обычно содержит имя файла, путь к нему в этой самой временной папке, код ошибки загрузки (если была ошибка), размер и т.п. Но так происходит в обычном мире, на обычном веб-сервере. У вас же в качестве сервера МК :)
Я бы на вашем месте сделал так: выдал бы с МК вот эту страничку, что я вам предложил, и попробовал бы с ПК отправить через нее на МК файл, а дальше разобрал бы то, что пришло на МК, уверен, там все было бы понятно.
0
Ах да, в вашем случае, думаю, атрибут «action» у формы вообще можно не указывать. Тогда обычно обращение идет к тому же скрипту, что выдал форму, но в вашем случае вам вообще все равно на скрипты, как я понимаю.
Впрочем, вам и еще много чего можно выкинуть, атрибутs id и name у формы, например. Атрибут name у «submit» тоже нафиг, чтобы лишние данные не слать.
0
Ну почему же, надо же разобраться, к какому обработчику файл пришел. Так что action я бы оставил.
0
Тоже верно, туда вместо имени скрипта в данном случае можно писать, наверное, некий идентификатор действия, которое мы на МК присылаем, например, action=«file_to_sd» — дескать: «Эй, МК, мы шлем тебе файл, и ты его должен сохранить на карточку!»
0
Спасибо всем за ответы. Трава в этот раз похоже забористая, ушел курить комменты…
0
Разница очень простая. POST создаёт объект, и адрес запроса является точкой входа на метод для создания новых объектов. PUT изменяет существующий объект, и адрес запроса должен на такой объект указывать. В терминах CRUD метод POST — это CREATE, а PUT — UPDATE. Какую разницу для них задумывали можно подробнее прочитать здесь: www.w3.org/Protocols/rfc2616/rfc2616-sec9.html.
Если тебе нужно просто загружать файлы, то по смыслу тебе подойдёт POST.
0
блин, не дочитал что этот коммент есть уже и сам написал то же самое
0
Маленький ликбез по методам HTTP
— GET — получить ресурс
— POST метод используется для создания ресурса
— PUT — используется для обновления ресурса (в новой спецификации появился метод PATCH как основной для этого)

Используются эти методы серверами для правильного роутинга

Проще говоря если серверу не всё равно каким к нему способом обращаются то один и тот же запрос, переданный POST создаст ресурс (например коммент к страничке) а методом PUT обновит его

И в браузере кстати с PUT всё ок, просто большинству людей не приходится им пользоваться

если есть вопросы — вы спрашивайте
0
Спасибо за разъяснения. Сейчас пока отлавливаю пару старых багов, потом вплотную займусь экспериментами и отпишусь о результатах.
0
эм, а расскажите, пожалуйста, как вы сделаете PUT из браузера?
0
например так

function restUpdate(options) {
    options = jQuery.extend(options, {type:"PUT"});
    return jQuery.ajax(options);
}


кусок кода из моего проекта. Проблема то в чем? Или js уже не браузер?
0
да, ок. я подразумевал чистый html, потому что топикстартеру нужен был простой метод, а тут уже jQuery тащим ради того, чтобы поменять 4 буквы в начале запроса на 3.

Если уж на то пошло, то можно ему предложить и файлы через FileApi читать, драг-н-дроп сделать и прочие плюшки.
0
Специально для вас залез читать спецификацию
рабочий метод, передается нормально, только doctype указать надо потому как для форм в HTML5 эти значения атрибута method признаны устаревшими (рекомендуется использовать JS)

Ссылочка на w3
0
> Using PUT and DELETE as HTTP methods for the form element is no longer supported.
и это в драфте спецификации, в браузерах никогда и не поддерживалось, кроме ночных сборок FF и Chrome; потому и из html5 выкинули
0
Да что вы говорите — а внимательно прочитать " for the form element " может стоит?
Да и вообще про архитектуру REST.
Ну и крайний случай написать элементарную html'ку с формой в которой стоит PUT и указать doctype, и попробовать — религия не позволяет?
0
1. я про форму и говорил
2. религия мне как раз позволяет: jsfiddle.net/23vCd/3/
жмём кнопочки, и внимательно смотрим в логи HTTP
0
doctype — не, не слышал…
0
внимательно смотрим и удивляемся view-source:http://jsfiddle.net/23vCd/3/show/
0
да да, внимательно смотрим, видим iframe с DOCTYPE html, материмся, вспоминаем про линку выше, материмся её раз, читаем про DOCTYPE
0
и уж тем более

<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" «www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd»>

я могу отличить от
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" «www.w3.org/TR/html4/strict.dtd»>
0
я уже не понимаю, что вы там не можете отличить. у вас есть пример, где method=put у формы будет таки работать?
0
То есть это работает как просто вы не пробовали ;)

Кстати, ещё забыл сказать про метод DELETE. Думаю понятно его назначение
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.