Интернет и кодирование · 5 минута чтения
cURL для извлечения: перемещение запроса с терминала в браузер
Преобразование cURL для получения — это обычный путь от документации API к рабочему коду внешнего интерфейса: самый быстрый способ понять API — это команда cURL, скопированная из его документации, а самый быстрый способ отправить ее — `fetch`. Преобразование между ними в основном механическое — флаги сопоставляются с объектом параметров — но две вещи обычно нарушают преобразование: кодировки тела и модель безопасности браузера, которая не имеет эквивалента в терминале.
Обновлено
Как отображаются флаги
- `-X POST` → `method: "POST"` (или выберите метод из `-d`).
- `-H "Content-Type: application/json"` → запись в `headers`.
- `-d '{"a":1}'` → `body: JSON.stringify(...)`; cURL отправляет его в закодированном виде, если вы не укажете иное.
- `--data-binary @file` → тело `Blob`, `FormData` или `ArrayBuffer`, а не строка.
- `-u user:pass` → заголовок `Authorization: Basic …`, построенный на основе base64 `user:pass`.
- `-F name=@file` → `FormData` с `File`, так выражается загрузка файлов.
await fetch('https://api.example.com/v1/orders', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer ' + token,
},
body: JSON.stringify({ sku: 'YB-1', qty: 2 }),
});
CORS: та часть, о которой cURL никогда не приходилось думать
cURL работает вне модели безопасности браузера, поэтому он может вызывать любой хост, который отвечает. `fetch` на странице привязано CORS: сервер должен разрешить ваш источник, и для всего, что выходит за рамки простых запросов, он также должен правильно ответить на предполетный `OPTIONS`. Преобразованная команда, которая отлично работает в терминале, может завершиться неудачей в браузере с непрозрачной сетевой ошибкой именно по этой причине — и никакое редактирование заголовка в запросе не исправит это, потому что разрешение должно прийти с сервера.
Если при получении сообщения CORS произошел сбой, исправление находится на API или на вашем прокси-сервере, а не в JavaScript. Никогда не обходите эту проблему, добавляя ключ API в клиентский код, чтобы «избежать» проблемы.
Учетные данные, перенаправление и потоковая передача
Еще два поведения отличаются от терминала. Файлы cookie не отправляются, пока вы не укажете `credentials: "include"`, и сервер должен в ответ указать явное происхождение, а не подстановочный знак. За перенаправлениями по умолчанию следует `redirect: "follow"`, но при перенаправлении заголовок `Authorization` теряется во всех источниках, если только сервер не обрабатывает его, поэтому для аутентифицированных вызовов часто требуется `redirect: "manual"` и намеренное следование. Потоковые ответы считываются из `response.body` как `ReadableStream`, где cURL просто печатает по мере получения.
Фетч или аксиос?
`fetch` встроен и работает везде, где угодно; axios добавляет удобства — автоматический анализ JSON, перехватчики, читаемая ошибка для ответов, отличных от 2xx, прогресс загрузки в старых средах выполнения. Преобразованная команда cURL является надежной отправной точкой для любого из следующих вариантов: вставьте сгенерированные параметры в вызов axios, а заголовки и тело сохранятся без изменений.
Преобразование без утечек
Команды cURL, скопированные из реальных сеансов, обычно содержат токены живого носителя, ключи API или файлы cookie сеанса. Преобразование, выполняемое в браузере, сохраняет эти учетные данные на вашем компьютере, что является единственным разумным способом работы с запросом, который вы не вводили самостоятельно.
cURL для получения — часто задаваемые вопросы
Почему мой преобразованный запрос на выборку завершается ошибкой CORS?
Потому что браузер применяет одну и ту же политику происхождения, а cURL — нет. API должен отправить соответствующий заголовок `Access-Control-Allow-Origin` и обработать предполетные запросы. Проксирование через ваш собственный сервер является стандартным решением, когда сторонний API не разрешает исходный браузер.
Как отправить данные формы с помощью fetch вместо JSON?
Используйте объект `FormData` в качестве тела и позвольте браузеру установить составную границу — не устанавливайте `Content-Type` самостоятельно, поскольку значение включает в себя маркер границы, который генерирует браузер. Это также касается загрузки файлов с флагами `-F`.
Отправляет ли fetch файлы cookie по умолчанию?
Нет. Запросы с одним и тем же источником включают файлы cookie, когда применяется `credentials: "same-origin"`, но для вызовов между источниками требуется `credentials: "include"`, и сервер должен в ответ указывать явное происхождение, а не подстановочный знак, чтобы ответ можно было прочитать.
Инструменты, упомянутые в этом посте
Еще статьи для чтения
5 минута чтения
Кодировка URL: когда бежать, а когда что-то ломаешь
URL правильно кодировать и декодировать — зарезервированные символы плюс %20, encodeURI и encodeURIComponent, а также ошибки двойного кодирования в неработающих ссылках.
5 минута чтения
Base64 декодировать и кодировать: для транспорта, а не для
Base64 декодировать и кодировать в браузере — правило размера 4/3, отступы, вариант base64url и ошибка Unicode, из-за которой декодированный текст выглядит как мусор.
6 минута чтения
JSON форматтер: красивый, минимизированный и действительно
Средство форматирования JSON, которое красиво печатает, минимизирует и проверяет точные местоположения ошибок, а также пять синтаксических ошибок, стоящих почти за каждой недопустимой ошибкой JSON.