Как отправить необработанные двоичные данные через HTTP в node.js?

Из серверной части node.js мне нужно отправить HTTP-сообщение на конечную точку REST. Конечной точке требуются некоторые параметры, которые она ожидает найти в HTTP-сообщении. Некоторые параметры достаточно просты: в качестве аргумента требуется число или строка. Но одним из параметров является «загружаемое необработанное содержимое двоичного файла», и это меня озадачило. Насколько я понимаю, параметры нужно собрать в строку, чтобы поместить в тело HTTP-запроса; Как добавить необработанные двоичные данные в строку? Очевидно, что для того, чтобы он был в строке, это не могут быть необработанные двоичные данные; его нужно закодировать в символы.

Рассматриваемой конечной точкой является API загрузки мультимедиа в Твиттер. Параметр «необработанные двоичные данные» называется media. Ниже приведен неполный фрагмент кода, показывающий основную суть того, что я пробовал. В частности, строка, в которой я строю строку requestBody. Я не думаю, что это правильно, потому что конечная точка возвращает сообщение «неверный запрос».

var https = require("https");

var base64ImageData = /* (some base 64 string here) */;

var options = {
    host: "api.twitter.com",
    path: "/1.1/media/upload.json",
    method: "POST",
    headers: {
        "Content-Type": "multipart/form-data"
    }
};
var request = https.request(options, function(response) {});
var requestBody = "media_id=18283918294&media = " + Buffer.from(base64ImageData, "base64").toString("binary");
request.write(requestBody);
request.end();

Также стоит отметить, что сами Twitter отмечают следующее крайне запутанное заявление:

«При публикации изображений, закодированных в base64, обязательно установите «Content-Transfer-Encoding: base64» в графической части сообщения».

Источник: https://developer.twitter.com/en/docs/media/upload-media/uploading-media/media-best-practices

Это может быть частью ответа на мой вопрос, но я не понимаю: Как применить разные заголовки к разным частям HTTP-сообщения? Поскольку, очевидно, данные изображения должны иметь заголовок Content-Transfer-Encoding «base64», в то время как остальная часть сообщения HTTP не ...

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
1 561
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

How do I apply different headers to different parts of the HTTP message?

В этом суть типа контента multipart/form-data. Сообщение, состоящее из нескольких частей, выглядит так:

Content-Type: multipart/form-data; boundary=---foo---

---foo---
Content-Disposition: form-data; name = "datafile1"; filename = "r.gif"
Content-Transfer-Encoding: base64
Content-Type: image/gif

// data goes here
---foo---
Content-Disposition: form-data; name = "datafile2"; filename = "g.png"
Content-Transfer-Encoding: base64
Content-Type: image/png

// another file's data goes here
---foo---

Вы, вероятно, не хотите собирать все это вместе. Существует множество хороших библиотек для составления сложных POST-запросов. Например: https://www.npmjs.com/package/form-data

Спасибо, но меня по-прежнему сбивает с толку конкретный случай с Твиттером. Их документация строго подразумевает, что данные файла просто должны быть предоставлены в виде формата параметра URL. developer.twitter.com/en/docs/media/upload-media/api-referen‌​ce/…. См. предоставленный пример: command=APPEND&media_id=123&segment_index=2&media_data=123 Можете ли вы предположить, почему это может быть так? Также, чтобы было ясно, в вашем примере сообщения, состоящего из нескольких частей, все это идет в теле? Входит ли boundary=--foo-- в заголовок Content-Type?

CircuitScholar 29.05.2019 04:22

@CircuitScholar — это параметры запроса, они не являются частью тела запроса. Когда этот формат используется в теле запроса, тип контента — application/x-www-form-urlencoded.

Jake Holzinger 29.05.2019 04:25

Документы @CircuitScholar в Твиттере всегда были немного дерьмовыми. Перестаньте предполагать последствия — есть вероятность, что если что-то странное/бессмысленное в их документах, это просто Твиттер — это Твиттер. Вы не отправляете большие многомегабайтные данные файла в качестве параметра URL.

ceejayoz 29.05.2019 04:27

(Примечание: см. пошаговое руководство на developer.twitter.com/ru/docs/media/upload-media/… для фрагментированных загрузок и используйте этот бит: «Чтобы увидеть полные заголовки запросов и ответов при использовании twurl, используйте параметр -t для включения режима трассировки». )

ceejayoz 29.05.2019 04:29

Другие вопросы по теме