Что JavaScript-разработчику следует знать о Curl

от автора

Доброго времени суток, друзья!

Представляю Вашему вниманию перевод статьи «What JavaScript Developers Should Know About Curl» автора Valery Karpov.

Curl — это популярный инструмент командной строки, часто используемый для отправки HTTP-запросов. Curl поддерживает большое количество протоколов, однако как Node.js-разработчик вы, скорее всего, будете использовать его для отпраки http-запросов к RESTful API.

Документация curl представляет собой перечень из 383 флагов командной строки, поэтому в ней очень трудно найти то, что ищешь. В этой статье я хочу поделиться с вами некоторыми часто используемыми мной шаблонами. Для примеров будет использоваться сервис httpbin.org.

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

Для начала убедитесь в том, что у вас установлен curl, выполнив команду curl --version.

$ curl --version curl 7.58.0 (x86_64-pc-linux-gnu) libcurl/7.58.0 OpenSSL/1.1.1 zlib/1.2.11 libidn2/2.0.4 libpsl/0.19.1 (+libidn2/2.0.4) nghttp2/1.30.0 librtmp/2.3 Release-Date: 2018-01-24 Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp smb smbs smtp smtps telnet tftp  Features: AsynchDNS IDN IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz TLS-SRP HTTP2 UnixSockets HTTPS-proxy PSL  

Для отправки запроса необходимо запустить curl url. Например, для отправки GET-запроса к https://httpbin.org/get?answer=42 следует запустить curl https://httpbin.org/get?answer=42.

$ curl https://httpbin.org/get?answer=42 {   "args": {     "answer": "42"   },    "headers": {     "Accept": "*/*",      "Host": "httpbin.org",      "User-Agent": "curl/7.58.0",      "X-Amzn-Trace-Id": "Root=1-5ee8d737-b39c6a466892725bbb52b916"   },    "origin": "69.84.111.39",    "url": "https://httpbin.org/get?answer=42" } 

После успешного завершения запроса curl возвращает тело http-ответа. Для того, чтобы заставить curl вернуть весь ответ, включая заголовки, используйте флаг -i.

$ curl -i https://httpbin.org/get?answer=42 HTTP/2 200  date: Tue, 16 Jun 2020 14:30:57 GMT content-type: application/json content-length: 801 server: istio-envoy access-control-allow-origin: * access-control-allow-credentials: true x-envoy-upstream-service-time: 2  {   "args": {     "answer": "42"   },    "headers": {     "Accept": "*/*",      "Content-Length": "0",      "Host": "httpbin.org",      "User-Agent": "curl/7.58.0",      "X-Amzn-Trace-Id": "Root=1-5ee8d7a1-cb3954c09299eb9e0dff70a6",      "X-B3-Parentspanid": "dffc55451e64b5fc",      "X-B3-Sampled": "0",      "X-B3-Spanid": "8e233a863fb18b6c",      "X-B3-Traceid": "45bd12a9067fb5c0dffc55451e64b5fc",      "X-Envoy-External-Address": "10.100.91.201",      "X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/httpbin-istio/sa/httpbin;Hash=c1ff14671b3e24ee794f9a486570abf8ccc9d622846611d3f91a322db4d480cd;Subject=\"\";URI=spiffe://cluster.local/ns/istio-system/sa/istio-ingressgateway-service-account"   },    "origin": "69.84.111.39,10.100.91.201",    "url": "http://httpbin.org/get?answer=42" } 

Это полный http-ответ. Заголовками ответа являются строки от date: до x-envoy-upstream-service-time:.

Загрузка файлов

Wget — самый распространенный инструмент для загрузки файлов посредством командной строки. Он входит в комплект большинства диструбутивов Linux. Однако в OSX его нет.

Команда wget url аналогична команде curl -OL url. Опция — это опция --remote-name, которая говорит curl сохранить тело ответа в локальном файле. Опция -L говорит curl следовать перенаправлениям.

Например, ниже представлено изображение с Unsplash, его URL — https://images.unsplash.com/photo-1506812574058-fc75fa93fead.

Для загрузки этого изобюражения необходимо выполнить следующее:

$ curl -OL https://images.unsplash.com/photo-1506812574058-fc75fa93fead   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current                                  Dload  Upload   Total   Spent    Left  Speed 100 12.1M  100 12.1M    0     0  3927k      0  0:00:03  0:00:03 --:--:-- 3927k 

Опция -O говорит curl использовать строку после последнего / в качестве имени файла. В приведенном примере изображение будет сохранено в текущей директории с именем photo-1506812574058-fc75fa93fead. Для определения имени файла используйте опцию (строчная буква «о»).

$ curl -o miami-beach.jpg https://images.unsplash.com/photo-1506812574058-fc75fa93fead   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current                                  Dload  Upload   Total   Spent    Left  Speed 100 12.1M  100 12.1M    0     0  6083k      0  0:00:02  0:00:02 --:--:-- 6083k $ ls -l miami-beach-jpg -rw-rw-r-- 1 val val 12788445 Jun 16 11:03 miami-beach.jpg 

Отправка авторизованного запроса

Заголовок авторизации используется для включения в запрос данных для авторизации при обращении к RESTful API. Для добавления указанных данных необходимо использовать флаг -H. Например, если ваш ключ интерфейса (API key) my-secret-token, вы можете включить его в http-запрос следующим образом:

$ curl -H "Authorization: my-secret-token" https://httpbin.org/get {   "args": {},    "headers": {     "Accept": "*/*",      "Authorization": "my-secret-token",      "Host": "httpbin.org",      "User-Agent": "curl/7.58.0",      "X-Amzn-Trace-Id": "Root=1-5ee8e1a5-a3aa30e0765a7980b04ca4a0"   },    "origin": "69.84.111.39",    "url": "https://httpbin.org/get" } 

Обратите внимание, что httpbin.org возвращает заголовки http-запроса в теле ответа в свойстве headers.

Curl также поддерживает авторизацию по-умолчанию посредством флага -u. В следующем примере мы отправляем запрос с именем пользователя user и паролем pass:

$ curl -i -u "user:pass" https://httpbin.org/basic-auth/user/pass HTTP/2 200  date: Tue, 16 Jun 2020 15:18:45 GMT content-type: application/json content-length: 47 server: istio-envoy access-control-allow-origin: * access-control-allow-credentials: true x-envoy-upstream-service-time: 1  {   "authenticated": true,    "user": "user" } 

Вот что происходит при отправке неправильного имени пользователя или пароля:

$ curl -i -u "user:wrongpass" https://httpbin.org/basic-auth/user/pass HTTP/2 401  date: Tue, 16 Jun 2020 15:18:51 GMT content-length: 0 server: istio-envoy www-authenticate: Basic realm="Fake Realm" access-control-allow-origin: * access-control-allow-credentials: true x-envoy-upstream-service-time: 12 

Отправка POST-запроса, содержащего JSON

Флаг -X говорит curl, какой метод следует использовать: PUT, POST и т.д. По-умолчанию curl использует метод GET, поэтому писать curl -X GET не нужно.

Флаг -X часто используется совместно с флагом -d, позволяющим добавить тело запроса. В следующем примере показано как отправить POST-запрос, содержащий некоторый json:

$ curl -X POST -d '{"answer":42}' https://httpbin.org/post {   "args": {},    "data": "",    "files": {},    "form": {     "{\"answer\":42}": ""   },    "headers": {     "Accept": "*/*",      "Content-Length": "13",      "Content-Type": "application/x-www-form-urlencoded",      "Host": "httpbin.org",      "User-Agent": "curl/7.58.0",      "X-Amzn-Trace-Id": "Root=1-5ee8e3fd-8437029087be44707bd15320",      "X-B3-Parentspanid": "2a739cfc42d28236",      "X-B3-Sampled": "0",      "X-B3-Spanid": "8bdf030613bb9c8d",      "X-B3-Traceid": "75d84f317abad5232a739cfc42d28236",      "X-Envoy-External-Address": "10.100.91.201",      "X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/httpbin-istio/sa/httpbin;Hash=ea8c3d70befa0d73aa0f07fdb74ec4700d42a72889a04630741193548f1a7ae1;Subject=\"\";URI=spiffe://cluster.local/ns/istio-system/sa/istio-ingressgateway-service-account"   },    "json": null,    "origin": "69.84.111.39,10.100.91.201",    "url": "http://httpbin.org/post" } 

Обратите внимание, что по-умолчанию значением заголовка Content-Type является application/x-www-form-urlencoded. Для json это является неверным, поэтому для определения Content-Type следует использовать флаг -H:

$ curl -X POST -d '{"answer":42}' -H "Content-Type: application/json" https://httpbin.org/post {   "args": {},    "data": "{\"answer\":42}",    "files": {},    "form": {},    "headers": {     "Accept": "*/*",      "Content-Length": "13",      "Content-Type": "application/json",      "Host": "httpbin.org",      "User-Agent": "curl/7.58.0",      "X-Amzn-Trace-Id": "Root=1-5ee8e45e-ad875af4f83efd4379b86c34",      "X-B3-Parentspanid": "5f4f33d1c5ea13aa",      "X-B3-Sampled": "0",      "X-B3-Spanid": "a062c9bf2ebfd4bd",      "X-B3-Traceid": "44aa8d62412ae34d5f4f33d1c5ea13aa",      "X-Envoy-External-Address": "10.100.86.47",      "X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/httpbin-istio/sa/httpbin;Hash=2f0b3331fe4d512975b4b82583a55dd5d1196023d0dfce9e0abed246991c5b67;Subject=\"\";URI=spiffe://cluster.local/ns/istio-system/sa/istio-ingressgateway-service-account"   },    "json": {     "answer": 42   },    "origin": "69.84.111.39,10.100.86.47",    "url": "http://httpbin.org/post" } 

Отправка PUT-запроса, содержащего JSON-файл

Флаг -d также поддерживает отправку данных из локальных файлов.

Например, представим, что у нас есть файл data.js, содержащий такие данные:

{"answer": 42} 

Для отправки PUT-запроса с этим файлом в качестве тела запроса вы можете присвоить флагу -d значение @data.json. Префикс @ говорит curl загрузить тело запроса из файла data.json:

$ curl -X PUT -d '@data.json' -H "Content-Type: application/json" https://httpbin.org/put {   "args": {},    "data": "{\"answer\":42}",    "files": {},    "form": {},    "headers": {     "Accept": "*/*",      "Content-Length": "13",      "Content-Type": "application/json",      "Host": "httpbin.org",      "User-Agent": "curl/7.58.0",      "X-Amzn-Trace-Id": "Root=1-5ee8e745-37c4ef06326b7b4354a16b94",      "X-B3-Parentspanid": "a4f8f91f4f1b051e",      "X-B3-Sampled": "0",      "X-B3-Spanid": "a018b1a3fcebdc68",      "X-B3-Traceid": "7b48b01dc3f632eea4f8f91f4f1b051e",      "X-Envoy-External-Address": "10.100.91.201",      "X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/httpbin-istio/sa/httpbin;Hash=6035260d9d551af6c1907270653214e8d3195abbdd19078c1c84fd9a4106f260;Subject=\"\";URI=spiffe://cluster.local/ns/istio-system/sa/istio-ingressgateway-service-account"   },    "json": {     "answer": 42   },    "origin": "69.84.111.39,10.100.91.201",    "url": "http://httpbin.org/put" } 

Заключение

Резюмируя, вот опции curl, которые я нахожу самыми полезными:

  • -X определяет метод запроса, например, curl -X POST url
  • -d определяет тело запроса в виде строки в PUT и POST-запросах. Используйте @ для извлечения данных из файла
  • -H определяет заголовок запроса, например, curl -H "Authorization: my-secret-token" url
  • -u аутентификационные данные для стандартной авторизации
  • -O сохраняет тело запроса в файл
  • -i показывает полный ответ, включая заголовки

Curl — полезный инструмент взаимодействия с API посредством командной строки, независимо от того, сторонний это API или API, который вы разрабатываете. Для быстрого тестирования curl подходит лучше, чем Axios в Node.js или настройка запроса в Postman, если вы знакомы с их синтаксисом.

Благодарю за потраченное время. Надеюсь, оно было потрачено не зря.

ссылка на оригинал статьи https://habr.com/ru/post/508592/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *