Curl — отправка json-данных составной формы из файла

#curl

Вопрос:

Мне нужно отправить POST запрос с помощью curl через командную строку. Тип контента должен быть multipart/form-data

Моя полезная нагрузка-JSON, но она действительно большая, поэтому я не могу отправить ее напрямую через curl (список аргументов слишком длинный). Вместо этого мне нужно запросить содержимое через файл

Без получения содержимого из файла все работает нормально

 curl "https://domain/endpoint.php" 
 -F "jsondata={"jsonkey":"jsonvalue"};type=application/json"
 

=>

 array(1) {
  ["jsondata"]=>
  string(23) "{"jsonkey":"jsonvalue"}"
}
 

(отправляется в виде составных/форм-данных)

Но когда я помещаю тот же (небольшой тест) json в файл и использую его в своей команде curl. Результат на стороне сервера отличается

 curl "https://domain/endpoint.php" 
 -F "jsondata=@curl_data3.json;type=application/json"
 

=>

 array(1) {
  ["jsondata"]=>
  array(5) {
    ["name"]=>
    string(15) "curl_data3.json"
    ["type"]=>
    string(16) "application/json"
    ["tmp_name"]=>
    string(14) "/tmp/php5k58m4"
    ["error"]=>
    int(0)
    ["size"]=>
    int(23)
  }
}
 

Файл (curl_data3.json) просто содержит {"jsonkey":"jsonvalue"}

Похоже, я просто отправляю сам файл, а не содержимое файла :-/

Ответ №1:

HTML-формы, для которых были разработаны составные данные/формы, поддерживают несколько видов полей ввода и, в частности, отличают поля ввода, которые являются «загрузкой файлов», от других полей. Поля, которые являются файлами, содержат метаданные о файле. Видишь https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#multipart/form-data-encoding-algorithm и как указано в RFC7578, особенно 4.2:

Для [части составных данных/данных формы], которая представляет содержимое файла, также следует указать имя файла, используя параметр «имя файла» в поле заголовка «Содержимое». Имя файла не является обязательным ….

curl -F field=@file реализует это в соответствии со стандартом, и, по-видимому, ваш сервер расширяет это в структуру json, которую вы получаете.

Если вы вместо этого используете curl -F field=<file (с кавычками по мере необходимости, потому < что это специально в оболочке, CMD или PS), он отправляет содержимое файла в виде обычного поля, не являющегося файлом. Смотрите справочную страницу:

[-F] позволяет загружать двоичные файлы и т.д. Чтобы заставить часть «содержимое» быть файлом, добавьте в имя файла знак@. Чтобы просто получить часть содержимого из файла, префикс имени файла с символом Разница между @ и < заключается в том, что @ заставляет файл прикрепляться к сообщению в качестве загрузки файла, в то время как