Правильный способ отправки multipart / form-data с использованием `fetch` или` request` - PullRequest
0 голосов
/ 06 января 2019

Это структура данных, которые я хочу отправить на сервер:

{
   attachment: [File],
   foo: String,
   bar: String
}

Как видите, я пытаюсь отправить массив файлов вместе с некоторыми другими данными. Для хранения всех этих данных я использовал конструктор FormData(), предоставленный в официальном API JavaScript. Я заполняю formData так:

for (let i = 0; i < this.state.files.length; i++) {
    let f = this.state.files[i];
    this.formData.append('attachment', f, f.name);
}
this.formData.append('foo', this.state.foo);
this.formData.append('bar', this.state.bar);

Sidenote: использование React, react-dropzone для загрузки файла. Я сейчас пытаюсь отправить эти данные на сервер. Сначала я попытался использовать API Fetch, например:

fetch(url, {
    method: method,
    body: data,
    headers: {
      ...authHeader(authToken)
    }
}

Без особого успеха. Метод POST. authHeader(authToken) только генерирует Authorization: Bearer .... Проблема в том, что я думаю, что указанные заголовки переопределяются моим заголовком аутентификации.

Итак, я попытался использовать request и request-promise-native. Я сделал что-то вроде:

rp({
    url,
    method,
    headers: {
      ...authHeader(authToken)
    },
    formData: data
});

С похожими результатами. Как правильно отправлять данные такого рода с помощью заголовка авторизации и массива файлов из FormData?

Ответы [ 2 ]

0 голосов
/ 06 января 2019

Для дальнейшего использования мне удалось отправить данные со следующей конфигурацией:

fetch(url, {
    method: method,
    body: data,
    headers: {
        'Accept': 'application/json',
        ...authHeader(authToken)
    }
})

То есть, проход через заголовок Accept, похоже, решил проблему. Также обратите внимание, что заголовок Content-Type не установлен, что позволяет браузеру устанавливать его самостоятельно.

0 голосов
/ 06 января 2019

Это опции, доступные в объекте выборки

fetch(url, {
            method: "POST", // *GET, POST, PUT, DELETE, etc.
            mode: "cors", // no-cors, cors, *same-origin
            cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached
            credentials: "same-origin", // include, *same-origin, omit
            headers: {
                "Content-Type": "application/json",
                // "Content-Type": "application/x-www-form-urlencoded",
            },
            redirect: "follow", // manual, *follow, error
            referrer: "no-referrer", // no-referrer, *client
            body: JSON.stringify(data), // body data type must match "Content-Type" header
        })

Если вам нужно отправить какой-нибудь пользовательский заголовок на сервер, просто напишите его так:

headers: {
           "My-Custom-Header": "Custom-Header-Value",
         }

И поскольку вы хотите отправить данные из нескольких частей, вам нужно просто добавить данные в тело запроса следующим образом:

body: formData 

Если у вас есть поля внутри тега формы, вы можете установить данные формы следующим образом:

var formData = new FormData(document.querySelector("form"));

Если вы используете http-аутентификацию, существуют разные схемы аутентификации, для справки используйте эту ссылку https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication

Если вы используете базовую авторизацию, вы должны использовать что-то вроде этого:

headers: {
           'Authorization': 'Basic '+btoa('username:password')
         }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...