Axios: Не удается получить .post с «Content-Type»: «multipart/form-data» для работы

Созданный на 11 мая 2016  ·  99Комментарии  ·  Источник: axios/axios

Сегодня я потратил несколько часов, пытаясь заставить почтовый запрос работать с несколькими параметрами и файлом, который мне нужно загрузить.

Мне удалось заставить его работать с чистым javascript и XMLHttpRequest, но он не работает с Axios. Что я делаю неправильно?

Вот код, который работает с XMLHttpRequest:

let data = new FormData();

data.append('action', 'ADD');
data.append('param', 0);
data.append('secondParam', 0);
data.append('file', new Blob([payload], { type: 'text/csv' }));

// this works
let request = new XMLHttpRequest();
request.open('POST', url);
request.send(data);

Какой будет версия «Axios»?

Вот одна из моих попыток (простая):

// this won't work
const config = { headers: { 'Content-Type': 'multipart/form-data' } };
    axios.post(url, data, config)
    .then(response => console.log(response))
    .catch(errors => console.log(errors));

Спасибо! И спасибо за отличную работу с Axios!

Самый полезный комментарий

@rafaelbiten Я только что пытался воспроизвести проблему, но безрезультатно. Я использовал следующий код:

const data = new FormData();

data.append('action', 'ADD');
data.append('param', 0);
data.append('secondParam', 0);
data.append('file', new Blob(['test payload'], { type: 'text/csv' }));

axios.post('http://httpbin.org/post', data);

Данные успешно отправлены на сервер:

screen shot 2016-05-12 at 9 12 19 pm

Все 99 Комментарий

Код выглядит хорошо для меня. (Вам не нужно устанавливать Content-Type, но это и не важно.) Что происходит, когда вы пытаетесь отправить запрос через axios?

Я заметил, что установка Content-Type или нет ничего не меняет в этом случае. Когда я пытаюсь отправить запрос с помощью Axios, кажется, что данные идут как пустая строка, поэтому серверная часть отвечает ошибкой, связанной с отсутствующими параметрами.

Я использовал 0.9.1, но проблема сохраняется на 0.11.0.

Пожалуйста, дайте мне знать, если есть что-то еще, что я могу сделать, чтобы отладить это, хорошо?
Спасибо @nickuraltsev !

Не могли бы вы взглянуть, как выглядят ваши запросы на панели Chrome Dev Tools Network, и, если возможно, предоставить скриншот?

@nickuraltsev посмотрите, поможет ли это:

screen shot 2016-05-11 at 2 56 12 pm

Я думаю, что заголовки запроса неверны.

Значит, нет запроса полезной нагрузки?

Ну, мы должны были бы, но данные идут как пустая строка. Я не знаю, что может его сломать (учитывая код, которым я поделился в своем первом посте).

Я понимаю. И для ваших запросов в Dev Tools нет раздела Request Payload, верно?

Возможно, проблема связана с заголовком. Когда тип контента установлен в объекте конфигурации в запросе, он объединяется, например
аксиос.пост(
'https://example.com/логин',
{emailAddress: электронная почта, пароль: hashedPassword},
{заголовки: {'тип контента': 'приложение/json'}}
);

тип содержимого заголовка входит как application/json,application/json
body не будет парситься в этом случае

@nickuraltsev верно! То, что вы видите на этом снимке экрана, — это все, что у меня есть в инструментах разработки.
@rrapant может быть прав, но я почти уверен, что установка 'Content-Type' или нет, по крайней мере, в этом случае ничего не меняла. Я должен был бы проверить еще раз, чтобы быть уверенным.

@rrapant Проблема с повторяющимися значениями типа контента была исправлена ​​в #317. Исправление будет включено в следующий релиз. Спасибо!

@rafaelbiten Я только что пытался воспроизвести проблему, но безрезультатно. Я использовал следующий код:

const data = new FormData();

data.append('action', 'ADD');
data.append('param', 0);
data.append('secondParam', 0);
data.append('file', new Blob(['test payload'], { type: 'text/csv' }));

axios.post('http://httpbin.org/post', data);

Данные успешно отправлены на сервер:

screen shot 2016-05-12 at 9 12 19 pm

@rafaelbiten Не могли бы вы попробовать отправить запрос с FromData на http://httpbin.org/post , как в моем фрагменте кода?

Закрытие на данный момент. Пожалуйста, не стесняйтесь открывать снова, если это необходимо.

Привет @nickuraltsev , у меня такая же проблема.

      var fd = new FormData();
      fd.append('file', this.refs.multipartfiles.files[0]);

            const config = { headers: { 'Content-Type': 'multipart/form-data' } };
            axios.post('/dataAPI/sendFile', {
                "UploadCommand": fd
              }, config)
              .then(function (response) {
                console.log(response);
              })
              .catch(function (error) {
                console.log(error);
              });

Пожалуйста, найдите снимок экрана с информацией в моем заголовке ниже,

image

У меня есть вопрос: _поддерживает ли axios отправку файлов данных, состоящих из нескольких частей, на сервер узла?_

@Sreekhar Я не знаю, сработает ли это, но не могли бы вы добавить FormData в качестве второго аргумента вместо того, чтобы заключать его в другой объект?
axios.post('/dataAPI/sendFile', fd, config)

Если вам нужно использовать «UploadCommand» в качестве имени части, где находится файл, вам нужно использовать это
fd.append('UploadCommand', this.refs.multipartfiles.files[0]);

@yungpanda Я нашел для этого альтернативу. Думаю, теперь мне придется воссоздать API. В любом случае, я попытаюсь проверить, работает ли это, я буду держать тему в курсе. Спасибо за ответ.

@Sreekhar Установите для Content-Type значение undefined, чтобы позволить браузеру изменить его на multipart/form-data и автоматически добавить границу

@nickuraltsev это минимальный пример, который не работает на узле:

const data = new FormData();

data.append('action', 'ADD');
data.append('param', 0);
data.append('secondParam', 0);

axios.post('http://httpbin.org/post', data).then(req => {
  console.log('Req done: ', req)
}).catch(err => {
  console.error('Error: ', err)
})

Ошибка: писать после конца

@krzkaczor Нашли ли вы какой-нибудь обходной путь для отправки multipart/form-data с помощью axios?

@PierreCavalet нет, вместо этого я использовал request-promise .

@krzkaczor спасибо, тоже вынужден переключиться

@krzkaczor Попробуйте добавить тип содержимого, если вы еще этого не сделали.

const config = { headers: { 'Content-Type': 'multipart/form-data' } };
let fd = new FormData();
fd.append('file',files[0])
return axios.post("http://localhost:5000/upload", fd, config)

@krzkaczor Я также сталкиваюсь с той же проблемой с axios и multipart/form-data. Можете ли вы опубликовать суть кода, который вы использовали с запросом-обещанием.

@dan-boa, иди сюда: https://gist.github.com/krzkaczor/bdbe09d4096b051a3c18387c4ca79a06 Он также показывает хак, как отправить строку в виде файла (установив путь)

Если кому интересно, вот пример использования FormData с axios . В основном вам нужно передавать данные в буфер и передавать правильные заголовки.

const concat = require("concat-stream")
const fd = new FormData()

fd.append("hello", "world")
fd.append("file", fs.createReadStream(file))
fd.pipe(concat(data => {
  axios.post("/hello", data, {
    headers: fd.getHeaders()
  })
}))

У меня была такая же проблема (в браузере, а не в узле). Оказалось, что это работает, если вы вообще не устанавливаете заголовок Content-Type и позволяете axios разобраться во всем (также проверьте, не установили ли вы этот заголовок по умолчанию в перехватчиках axios. Если вам нужны некоторые значения по умолчанию для остальных вызовов API, вы можете создать отдельный экземпляр axios для запросов FormData())

В итоге я использовал запрос-обещание на стороне узла при попытке загрузить на другой удаленный сервер.

Я переключился на запрос-обещание по той же причине. Любите аксиос иначе!

@guncha Ваш пример работал у меня в 0.15.3, пока я не попытался загрузить двоичный файл, который оказался закодирован как UTF8. Сообщение concat об использовании буфера устранило проблему.

const concat = require("concat-stream")
const fd = new FormData()

fd.append("hello", "world")
fd.append("file", fs.createReadStream(binaryFile))
fd.pipe(concat({encoding: 'buffer'}, data => {
  axios.post("/hello", data, {
    headers: fd.getHeaders()
  })
}))

В качестве альтернативы я бы использовал обещание:

const promise = new Promise((resolve) => {
  const fd = new FormData();
  fd.append("hello", "world");
  fd.append("file", fs.createReadStream(binaryFile));
  fd.pipe(concat({ encoding: 'buffer' }, data => resolve({ data, headers: fd.getHeaders() })));
});
promise.then(({ data, headers }) => axios.post('/hello', data, { headers }));
const callApi = (url, params) => {
  const formData  = new FormData()
  for(let name in params) {
    let param = params[name]
    if (typeof param === 'object') {
      param = JSON.stringify(params[name])
    }
    formData.append(name, param)
  }

  return axios.post(url, formData)
    .then(response => {
      console.log(response)
    })
}

@guncha работает на меня. Спасибо

такая же проблема здесь

просто добавьте границу к Content-Type :

const request = require('axios');
const FormData = require('form-data');
const fs = require('fs');

let data = new FormData();
data.append('file1', fs.createReadStream('./image1.jpeg'), 'image1.jpeg');
data.append('file2', fs.createReadStream('./image2.jpeg'), 'image2.jpeg');

let options = {
    method: 'POST',
    url: 'http://localhost:3200/upload',
    headers: {
        'Content-Type': `multipart/form-data; boundary=${data._boundary}`
    },
    data
};

return request(options)
    .then(response => {
        console.log(response);
    });

Привет,
Я получаю этот файл в формате json. Может ли кто-нибудь помочь мне, как мне преобразовать его в составной файл.
Используемая платформа — java8.
"body": "------WebKitFormBoundaryQsJGeBuR8e9dQ4Pm\r\nContent-Disposition: form-data; name=\"file\"; filename=\"backup prolog.txt\"\r\nContent-Type: text/plain\r\n\r\n%All the Pre-Defined relations\r\nconnected(hira,rohit,father).\r\nconnected(rohit,rakesh,father).\r\nconnected(ram,hira,father).\r\nconnected(kavri,hira,mother).\r\nconnected(hira,kavri,son).\r\nconnected(arun,vinayak,father).\r\nconnected(vinayak,arun,son).\r\nconnected(arun,shashi,husband).\r\nconnected(shashi,arun,wife).\r\nconnected(vinayak,vardaan,brother).\r\nconnected(vardaan,vinayak,brother).\r\nconnected(shashi,vinayak,mother).\r\nconnected(vinayak,shashi,son).\r\n\r\n\r\n\r\nconnected2(X,Y,D) :- connected(X,Y,D).\r\n%connected2(X,Y,D) :- connected(Y,X,D).\r\n\r\nnext_node(Current, Next,R, Path) :-connected2(Current, Next, R),not(member(Next, Path)).\r\n\r\nfunc(how,is,X,related,to,Y):-depth_first(X,Y,[X],P),write(P).\r\n%Procedure to Start the depth_first\r\ndepth_first(Goal, Goal, _, [Goal]).\r\n\r\ndepth_first(Start, Goal, Visited, [Start,is,R,of|Path]) :-next_node(Start, Next_node,R, Visited),depth_first(Next_node, Goal,[Next_node,R|Visited], Path).\r\n\r\n\r\n\r\n\r\n\r\n\r\n------WebKitFormBoundaryQsJGeBuR8e9dQ4Pm--\r\n"
Благодарность

Код работает в браузере, но не на узле.

const fdata = new FormData();
fdata.append('user', u);
fdata.append('hostnames', n.join(' '));
const host = localStorage.getItem('host');
const port = localStorage.getItem('port');
axios({
  url: `http://${host}:${port}/hosts/remove`,
  method: 'post',
  data: fdata
}).then(response => {
  if (response.status === 200) {
    console.log(response.data);
    console.log('Removed host successfully');
  }
  return null;
}).catch(er => console.log(er));

Привет @Sreekhar
Для меня я изменил конфигурацию на
const config = { headers: { 'Content-Type': 'application/json' } };
и это работало нормально

Пожалуйста, откройте снова, пока не будет какого-то последовательного ответа/рабочего процесса для этого. Похоже, что многие люди все еще испытывают проблемы с этим.

+1 повторно открыть

Сообщения HTTP, содержащие данные двоичного файла, отлично работают в axios v0.16.2.

// The following was tested successfully with axios v0.16.2

// Create a new form.  Note:  could also specify an existing form as
// the parameter to the FormData() constructor to copy all the elements
// from the existing form to the new one being created.

var tempFormData = new FormData();

var someNoteValue = 'Hello World';
var someAudioData = [];  // populate this with data from file, with MediaRecorder() etc.


// Add form fields

tempFormData.set('SomeNote', 'Hello World');
tempFormData.set('SomeRecording', someAudioData[0], 'SampleRecording.webm');


// Optional:  output list of form fields to the console for debugging

for (var pair of tempFormData.entries()) {
    console.log('Form field: ' + pair[0] + ', ' + pair[1]);
}


// Call Axios to post the form to myurl

axios({
    method: 'post',
    url: 'myurl',
    data: tempFormData,
    config: { headers: {'Content-Type': 'multipart/form-data' }}
})
    .then(function (response) {
        //handle success
        console.log(response);
    })
    .catch(function (response) {
        //handle error
        console.log(response);
    });

            }

Также при использовании буферов для представления файла это сработало для меня:

      const form = new FormData();
      const fileBuffer = new Buffer(
        'MM2 - noticeably shallower than the original - score: 101%', 'utf-8'
      );
      form.append('name', 'reviews.txt'); // additional form data field
      form.append('file', fileBuffer, 'original-file-name.bar');

      const res = await axios.post(`/uploadfile`, form, { headers: form.getHeaders() });

Важно отметить: любое из вышеперечисленных решений НЕ работает, если у вас есть какие-либо параметры данных по умолчанию, установленные в настройках по умолчанию экземпляра Axios. Вы также можете проверить, указали ли вы заголовок Content-Type по умолчанию в своем экземпляре Axios (через axios.defaults.headers и axios.defaults.parameters).

Это может быть не по делу, но проблема может быть связана с использованием body-parser на стороне сервера. Я боролся с похожей проблемой и наткнулся на этот пост:

https://philna.sh/blog/2016/06/13/the-surprise-multipart-form-data/

TL; DR — body-parser не обрабатывает multipart/form-data. Другими словами, проблема не в axios , а в body-parser . Возможно, поэтому буферные растворы, упомянутые выше, работают.

Я предполагаю, что эта функциональность предназначена для соображений безопасности, как указано здесь:

http://andrewkelley.me/post/do-not-use-bodyparser-with-express-js.html

Я надеюсь, что это поможет кому-то!

У меня такая же проблема. Я использую Axios 0.16.2 и отправка по XMLHttpRequest работает, но не по Axios.

У меня есть базовый объект FormData:

const formData = новые FormData();
formData.append('имя', 'textName');

Я попробовал предложение @Janekk :

axios({
      method: 'post',
      url,
      withCredentials: true,
      data: { formData },
    })

тогда предложение @faalkhah :

const config = { headers: { 'Content-Type': 'application/json' } };
    axios({
      method: 'post',
      url,
      withCredentials: true,
      data: { formData },
      config,
    })

или предложение @askona :

const config = { headers: { 'Content-Type': undefined } };
    axios({
      method: 'post',
      url,
      withCredentials: true,
      data: { formData },
      config,
    })

Заголовок запроса application/json , а formData пуст.

Я не знаю, как попробовать исправить @demeter-macik, потому что кажется, что он работает только в серверной части https://stackoverflow.com/a/13454425/968379

всем привет,
У меня точно такая же проблема
мой код в клиенте
`

    const url = '/file/uploadTest';
    const formData = new FormData();
    formData.append('file', file);
    formData.append('params1', value);
    formData.append('params2', value2)

    const config = {
        headers: {
            'Content-Type': 'multipart/form-data',
        }
    }
    axios.post(url,formData,config)`

на сервере парусов я записываю консоль req.body
Я обнаружил, что когда я вызываю запрос 10 раз, примерно 3-4 раза сервер не получает тело (тело пусто).
я проверил в devtool chrome, запрос все еще передает файл и тело в полезной нагрузке.
Я до сих пор не понял почему, но у меня есть решение

это заголовок запроса.

`код

    const url = '/file/uploadTest';
    const formData = new FormData();
    formData.append('file', file);
    formData.append('params1', value);
    formData.append('params2', value2)
    const config = {
        headers: {
            'Content-Type': 'multipart/form-data',
            'params1': value,
            'params2': value2
        }
    }
    axios.post(url,formData,config)`

Привет @Sreekhar ,
Вы решили проблему? Я не нашел решения, может кто-нибудь помочь мне, пожалуйста.
Также заранее спасибо

Привет,

Я пытался опубликовать multiformdata (это API Eztext SMS)
используя аксиомы с node.js.

Он хорошо работает для следующего кода,
вернуть новое обещание (функция (разрешить, отклонить) {

        var request = require("request");
        var options = {
            method: 'POST',
            url: 'https://app.eztexting.com/sending/messages',
            qs: {format: 'json'},
            formData:
                {
                    User: '**',
                    Password: '**',
                    'PhoneNumbers[0]': '8572222***',
                    Message: 'Appointment Reminder',
                    MessageTypeID: '1'
                }
        };
        request(options, function (error, response, body) {
            if (error) {
                console.log(error);
                reject(error);
            }
            else {
                console.log(response);
                resolve(response);
            }

            // console.log(body);
        });

Но это не работает с axios, так как SMS не отправляется, но я получаю код состояния 200 для следующего запроса: -
вар аксиос = требуется ('аксиос');

         axios.post('https://app.eztexting.com/sending/messages', {
             qs: { format: 'json' },
             headers: {
                 'Content-Type': 'application/x-www-form-urlencoded'
             },
             formData:
                 { User: '****',
                     Password: '2sH****5',
                     'PhoneNumbers[0]':'85722******',
                     Message: 'Hello Yahska',
                     MessageTypeID: 1 }
         })
             .then(function (response) {
                 console.log(response);
             })
             .catch(function (error) {
                 console.log(error);
             });

почему почтовый запрос выполняется с библиотекой «запрос», а не с Axios?

Вы пытались преобразовать данные из JSON в FormData без установки заголовка?
Заголовки для данных (т.е. помимо заголовков аутентификации) должны обрабатываться автоматически.

async function sendMessage(myJSONPayload){
  try{
    const data = convertJSON2FormData(myJSONPayload);

    const response = await axios.post('https://app.eztexting.com/sending/messages', {
  data
});
    console.log(response);
  } catch(ex){
    console error(err);
  }
}

sendMessage ({ User: '****',
                     Password: '2sH****5',
                     'PhoneNumbers[0]':'85722******',
                     Message: 'Hello Yahska',
                     MessageTypeID: 1 }
         });

Для преобразования из JSON в FormData используйте что-то вроде этого ответа

Помните, что с вложенными ключами сложно обращаться. Например, при отправке данных в наш бэкенд это работает, если мы сгладим их следующим образом:

{a: {b: 2}} --> formData.append("a.b",2)

такая же проблема здесь.

конечно, @michaelscheurer! Установки заголовков запроса недостаточно: вы должны отправить FormData, чтобы заставить его работать. Это объект браузера, который будет сериализован со всеми необходимыми границами для работы с запросом... ни axios, ни vanilla js не преобразуют данные JSON в FormData для вас. Axios распознает, что это FormData, а также установит для вас заголовки, поэтому вам не нужно их устанавливать.
Попробуйте следовать моим предыдущим подсказкам ответа...

@Iamuertepeluda
Я пробовал следующее в соответствии с вашим предложением, но не повезло, такое же поведение, как я получаю статус 200 в порядке, но SMS не отправляется со следующим запросом
вар аксиос = требуется ('аксиос');

    const FormData = require('form-data');

    const form = new FormData();

    //fo this jason I created a form
    // formData:
    // {
    //     User: '*****',
    //         Password
    // :
    //     '******',
    //         'PhoneNumbers[0]'
    // :
    //     '8****2763',
    //         Message
    // :
    //     'Appointment Reminder',
    //         MessageTypeID
    // :
    //     '1'
    // }

    form.append('User','****');
    form.append('Password','*****');
    form.append('PhoneNumbers[0]','*****');
    form.append('Message','Appointment Reminder');
    form.append('MessageTypeID','1');


         axios.post('https://app.eztexting.com/sending/messages', form,
    {
        qs: {format: 'json'},
        headers:
        {
                'content-type'
        :
            'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW'
        }
    }
)
             .then(function (response) {
                 console.log(response);
             })
             .catch(function (error) {
                 console.log(error);
             });

@ Ruchi2729 , вы используете node.js или браузер?

в браузере вам не нужно const FormData = require('form-data'); , так как FormData является родным.

Кроме того, попробуйте без установки заголовков и qs или попробуйте

axios.request({
 url: "https://app.eztexting.com/sending/messages"
 type: "post",
 data: form //the instance of FormData of your stub
});

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

@ Ruchi2729 Ruchi2729 Я вижу, ты используешь узел, извини.
Я помню, как однажды использовал form-data с axios, но не помню, работало ли это на самом деле.

Но вы уверены, что это правильный способ отправки SMS с помощью eztexting? Из их документов это кажется другим, например, вы должны использовать ключ API и собственный клиент узла...

Можем ли мы снова открыть это? Похоже, многие люди до сих пор сталкиваются с этим, в том числе и я. Например, этот запрос не доходит до сервера через axios, как ожидалось, но если я отправлю тот же файл через Postman как multipart/form-data , все будет работать.

screen shot 2018-03-26 at 12 22 35 am

Редактировать: моя проблема заключалась в попытке отправить data-uri в кодировке base64 в виде данных формы. Если кто-то еще борется с той же проблемой, вот пример кода для его преобразования:

async function importCsv(data: CsvImportData): Promise<void> {
    const formData = new FormData();
    const headers = {'Content-Type': 'multipart/form-data'};

    formData.append('csv', dataURItoFile(data.file, `upload_${Date.now()}.csv`));

    try {
      await axios.post('https://example.com/api/upload/csv', formData, {headers});
    } catch(e) {
      console.error(e);
    }
}

function dataURItoFile(dataURI: string, defaultFileName: string): File {
  let byteString: string;
  const [metadata, data] = dataURI.split(',');
  if (/base64$/.test(metadata)) {
    byteString = atob(data);
  } else {
    byteString = unescape(data);
  }

  const mimetype: string = metadata.split(':')[1].split(';')[0];
  const filename: string = (metadata.match(/name\=(.*);/) || [])[1] || defaultFileName;

  let dataView: Uint8Array = new Uint8Array(byteString.length);
  for (let i = 0; i < byteString.length; i++) {
    dataView[i] = byteString.charCodeAt(i);
  }
  return new File([dataView], filename);
}

Эй, я имею в виду этот документ: - https://www.eztexting.com/developers/sms-api-documentation/rest#Sending
какой документ вы имеете в виду для ключа API и всего?

@Ручи2729
Извините, я перепутал с Nexmo, это другой SMS-сервис, у которого есть собственный клиент для узла 😅

Но в любом случае, согласно документации, на которую вы ссылались , вы можете избежать FormData, установив format в json и позволив axios отправлять полезную нагрузку JSON (вы можете позволить ей угадывать заголовки неявно по формату полезной нагрузки)

https://app.eztexting.com/sending/messages?format=json

Я боролся с этим намного дольше, чем хочу признать, так что, надеюсь, это кому-то поможет. Я использую axios, экспресс и экспресс-загрузку файлов. Я могу успешно загрузить в Node параметры, которые я добавил к FormData. Я подбираю файлы с помощью req.files, а остальные данные формы подбираю с помощью req.body['yourfilename']

Сервер (Экспресс):

screen shot 2018-03-27 at 1 59 08 pm

router.post('/helper/amazon/upload', function(req, res) { if (!req.files) { return res.status(400).send('No files were uploaded.') } console.log(req.body.filename); return console.log(req.files);

Интерфейс (аксиос)

screen shot 2018-03-27 at 1 58 45 pm

const formData = new FormData(); formData.append('file', this.validFile); formData.append('filename', 'trails/' + this.$route.params.id.split('-')[0] + '/camping/'); axios.post( /api/helper/amazon/upload , formData, { headers: { 'Content-Type': 'multipart/form-data' } });

Результат:

screen shot 2018-03-27 at 2 02 11 pm

У меня та же проблема, я вижу, что успешно отправляю данные файла с помощью своих инструментов разработки, но внутри моего контроллера мой $request->file('file') пуст
Мой компонент

представить форму() {
this.formData = новые данные формы();
this.formData.append('файл',this.$refs.file.files[0]);
this.formData.append('анализ',this.analyticsForm.analysis);
this.formData.append('_method','PATCH');
axios.post('/аналитика',
this.formData
,{заголовки: {'Content-Type': 'multipart/form-data'}}).then(response => this.isSubmittedRedirect(false,'/sources/'+this.source+'/description'+'') )
.catch((ошибка) => console.log(ошибка))
},

Я обнаружил, что делать что-либо с FormData было проблемой, поскольку MVC, похоже, не любит получать что-либо таким образом, потому что вы должны указать Content-Type как multipart/form-data , и он выдавал исключение, когда я проверьте if (!Request.Content.IsMimeMultipartContent()) { throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType); } , как указано на сайте Microsoft: https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/sending-html-form-data-part- 2

Было лучше просто перевести мой файл в строку base64:
https://stackoverflow.com/questions/37134433/convert-input-file-to-byte-array/49676679#49676679

Этот пост может быть более подходящим для того, как это сделать, поскольку в этом примере я использовал DropZone:
https://stackoverflow.com/questions/32556664/getting-byte-array-through-input-type-file/49660172#49660172

И я расскажу об этом подробнее здесь :

Затем я мог бы создать объект JSON:

const myObj = {
   file = myBase64String,
   title = "myfileTitle.jpg"`
   type = "image/jpeg"`
}

Вместо использования axios я просто использовал XMLHttpRequest.

 const xhr = new XMLHttpRequest();

И откройте и установите заголовок:

 xhr.open('POST', '/api/FileUpload/Post', true);
 xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8' );
 xhr.withCredentials = true;

Я установил onreadystatechange для захвата ответа:

xhr.onreadystatechange = (response) =>
    if (xhr.readyState === 4 && xhr.status === 200) {
        console.log(response.target.responseText);
    }
}

и отправить:

 xhr.send(JSON.stringify(myObj));

Если вы используете axios, это, вероятно, будет:

try {
    var axios = require('axios');
    const config = {
        headers: {
            'Content-Type': 'application/json;charset=UTF-8',
        }
    }
    await axios.post('https://example.com/api/upload/post', myObj, config)
        .then(function (response) {
             console.log(response);
         })
         .catch(function (error) {
             console.log(error);
         });
}
catch(e) { console.log(e); }

На стороне MVC вам нужна соответствующая модель:

public class MyModel {
    public string file { get; set; }
    public string title { get; set; }
    public string type { get; set; }
}

а затем укажите это в качестве параметра в вашем почтовом вызове с тегом [FromBody]:

[System.Web.Http.HttpPost]
public virtual JsonResult<string> Post([FromBody]MyModel myModelObject)
{
    string strBase64FileString = myModelObject.file;
    string strTitle = myModelObject.title;
    string strFileType = myModelObject.type;

    return Json(JsonConvert.SerializeObject(new { file = myModelObject.file, title = myModelObject.title, myModelObject.type }));
}

Вам должны вернуть то, что вы отправили. Обратите внимание: если вы реализуете это как тест, делайте это с очень маленьким файлом, чтобы вы не ждали вечно с возможностью блокировки браузера/памяти вашей системы.

@navyjax2
Я делал, как вы сказали, он работал с небольшим файлом, но мне нужно отправить большой файл (> 250Mo), и да, это блокировало мой браузер.

Да, для этого вы можете разбить массив файлов на куски управляемого размера и отправить блоки, имея метод на другом (серверном) конце, который может их повторно комбинировать, и дать ему параметр, чтобы он знает, какой это фрагмент (1-й, 2-й, 3-й и т. д.) и сколько всего фрагментов следует ожидать, прежде чем он обработает файл на стороне сервера. Но я думаю, что бы вы ни делали с файлом такого размера, вам придется подождать, пока он сделает свое дело. Придется быть осторожным с управлением памятью, если вы делаете это также по частям, потому что вам нужно будет каждый раз очищать или повторно использовать свои переменные, а не каждый раз повторно создавать новые версии одних и тех же переменных. ты делаешь блок. Один из немногих случаев, когда глобальная переменная хороша — или просто устанавливается в поле модели при каждом запуске.

Я согласен с @epferrari , рассмотрите возможность повторного открытия этого вопроса.
Можно отправить строку base64 с FormData в chrome, но это невозможно сделать с помощью axios в узле (v8.9.3).
И это работает с node-fetch...

const fetch = require('node-fetch')
const axios = require('axios')
const FormData = require('form-data')
const base64Img = require('base64-img')

const b64 = base64Img.base64Sync('./test.jpg').split('base64,')[1]
const form = new FormData()
form.append('b64_data', b64)
const headers = form.getHeaders()

// with node-fetch it worked
fetch('http://some.url', {
  method: 'POST',
  body: form,
  headers,
}).then(res => res.text()).then(console.log).catch(console.log)

// not working with axios
axios({
  method: 'POST',
  url: 'http://some.url',
  data: form,
  headers,
}).then(console.log).catch(console.log)

=== обновление ===
Я не понимаю, я использую одни и те же заголовки для node-fetch и axios, и кажется, что они отправляют одни и те же данные формы на сервер, почему они заканчиваются по-разному?
Кстати, настоящий URL-адрес, который я публикую, взят отсюда , я делаю макет http-запроса браузера с помощью nodejs, чтобы отправить изображение на сервер и получить обратную ссылку.

Я обошел это, используя:

<input onChange="emitImageInfo(this)" type="file" multiple>

function emitImageInfo($event){
  let files = $event.target.files
  let formData = new FormData();

  for (let i = 0; i < files.length; i++)
      formData.append('image[' + i + ']', files[i])

  axios.post('file/upload', formData)
     .then((result) => { console.log('got it') })
     .catch((err) => { console.log(err) })
}

это сработало:

axios.post (localhost: 3000/items, formData, { заголовки: { 'Content-Type': 'multipart/form-data' }});

У меня точно такая же проблема

не работает с голангом

Просто найдите простой способ во Vue, но я думаю, что его можно использовать и в других ситуациях.😀
Серверная часть: Express.js и пакет экспресс-загрузки файлов.

<template>
  <div>
    <input type="file"
           name=""
           id="file-upload"
           multiple
           @change="filesChange($event.target.files)">
    <button @click="handleSubmit">Send</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      formData: new FormData(),
    };
  },
  methods: {
    filesChange(fileList) {
      // First: append file to FormData
      Array.from(Array(fileList.length).keys()).map(x => {
        this.formData.append(fileList[x].name, fileList[x]);
      });
    },
    handleSubmit() {
      // Append Text
      this.formData.append('username', 'Jeremy');

      // Append Number: Will be string
      this.formData.append('number', 9527);

      // Append Array: Need to be converted to a string
      this.formData.append('arrData', JSON.stringify([1, 2, 3]));

      // Append Array: Need to be converted to a string
      this.formData.append(
        'objData',
        JSON.stringify({ name: 'Jeremy', age: 28 })
      );

      this.axios({
        method: 'post',
        url: `file/multi-users`,
        data: this.formData,
      }).then(res => {
        console.log(res);
      });
    },
  },
};
</script>

capture

Даже мы столкнулись с той же проблемой. Заголовок content -type был удален из java-скрипта реакции, после чего он работал нормально. Раньше граница не устанавливалась, когда вы явно устанавливали тип содержимого

РЕДАКТИРОВАТЬ: После дальнейшего чтения об этом кажется, что Express был проблемой с моей стороны. Надеюсь, это может быть полезно для других

Та же проблема здесь. @nickuraltsev НАСТОЯТЕЛЬНО рекомендует открыть тему заново.

Я пытаюсь опубликовать файл на моем сервере узлов через axios, используя следующий код:

let ff = new FileReader();
ff.onload = (ev) => {
      var result = ev.target.result;
      console.log(`result: ${result} of type ${typeof(result)}`);
      axios.post('/test', {
                 file: result
                 })
                 .then((response) => {
                         console.log(`Response: ${response}`)
                  })
                  .catch((err) => {
                        console.log(`Test error: ${err}`);
                   })
}

var sampleFile = //getting the file here
ff.readAsArrayBuffer(sampleFile);

Тело запроса полностью пусто на стороне сервера.

Попытался отправить файл напрямую, прочитать файл как ArrayBuffer и прочитать файл как текст (хотя полезная нагрузка слишком велика), и все 3 не сработали.

Два года спустя:
Та же проблема...

@demeter-macik спасибо, добавление границ сработало для меня :smile:

    const form = new FormData();
    form.append('email', '[email protected]');
    form.append('phone_no', '63');
    form.append('phone_code', '9179303100');

    if (logo) {
      form.append('logo', logo);
    }

    const response = await axios({
      method: 'post',
      url: `${apiUrl}users`,
      data: form,
      headers: {
        'content-type': `multipart/form-data; boundary=${form._boundary}`,
      },
    });

Это определенно работает для меня — все браузеры, включая Safari iOS.

Мой код выглядит примерно так:

функция samplePost (конфигурация) {

// save reference this

let that = this;



// can optionally pull in form fields from an existing HTML form)

let myForm = document.getElementById('myForm');

let myFormData = new FormData(myForm);



// add in data from config.data if applicable

if (config && config.data) {

    that.objToStr(config.data, '', myFormData);



    for (let n2 in config.data) {

        if (config.data.hasOwnProperty(n2)) {

            myFormData.set(n2, config.data[n2]);

        }

    }

}



if (config.binaryFiles && config.binaryFiles.length > 0) {



    for (let i = 0; i < config.binaryFiles.length; i = i + 1) {

        let thisFile = config.binaryFiles[i];

        myFormData.append(thisFile.fieldName, thisFile.binaryData, thisFile.fileName)

    }

}





let axiosConfig = {

    method: 'post',

    url: config.url,

    data: myFormData,



    onUploadProgress: config.onUploadProgress,

};



if (config && config.binaryFiles && config.binaryFiles.length > 0) {

    axiosConfig.headers = {'Content-Type': 'multipart/form-data'};

}

else {

    axiosConfig.headers = {'Content-Type': 'application/x-www-form-urlencoded'};

}



const ax = axios.create();

// note that passing in config to the constructor is broken as of axios v0.19.0-beta.1

// So we work around by passing in config to the request() method



ax.request(axiosConfig)

    .then(function (response) {

        // handle success



        alert(response.data);



    })

};

// вызываем samplePost для загрузки

образецПост({

url: 'async',

data: {somefield: 'some value'}, //note: passes in as form fields



// optionally include array of binary files

binaryFiles: thisFileList

});

От: Антонио Васкес[email protected]
Отправлено: вторник, 11 сентября 2018 г., 11:23
Кому: axios/ axios [email protected]
Копия: DavidRueter [email protected] ; Комментарий [email protected]
Тема: Re: [axios/axios] Не удается заставить работать .post с Content-Type: multipart/form-data (#318)

4 часа и считая, чтобы сделать почтовый запрос из Safari. Все еще не происходит... какого черта, ребята??

Ни одно из решений здесь не сработало у меня... :(


Вы получаете это, потому что вы прокомментировали.
Ответьте на это письмо напрямую, просмотрите его на GitHub https://github.com/axios/axios/issues/318#issuecomment-420371510 или отключите ветку https://github.com/notifications/unsubscribe-auth/AFbi6JQBv06LTwL4z3HIAlvXAXDyps1- ks5uZ_9wgaJpZM4Ibm_z . https://github.com/notifications/beacon/AFbi6BSPfwPvNaWPFSdvtLKRYXS1m4uKks5uZ_9wgaJpZM4Ibm_z.gif

это сработало и для меня, спасибо @arvi

twiliosms = асинхронный (Codigo) => {

var FormData = требуют('данные формы');
вар фс = требуется ('фс');

переменная форма = новые данные формы();
form.append('Кому', '+524772773737');
form.append('От', '+737373737');
form.append('Тело', Codigo);

пытаться {
пусть axapi = ожидание axios(
{
URL: '2010-04-01/Accounts/AC8aa53c907943af79234414bb725c2cd3/Messages.json',
базовый URL: «https://api.twilio.com»,
заголовки: {'тип содержимого': multipart/form-data; boundary=${form._boundary} ,},
данные: форма,
авторизация: {
имя пользователя: 'AC8aa53c907943af79234414bb725c2cd3',
пароль: * ,
},
метод: 'пост',
}
)

} поймать (e) {console.error(e)}
}

Я блуждаю по этой библиотеке, все еще требующей самостоятельных обходных путей для сообщений с данными формы....

Любое обновление?

У меня есть аналогичная ошибка в NodeJS 10.11.0 и Axios 0.18.0 (см. № 1892). Я пробовал исправить @arvi , но это не работает.

для меня это работает:

let formData = new FormData(document.querySelector('#form'));

axios.post("/api/xxx", formData).then(console.log).catch(console.error)

и это не сработает

let formData = new FormData(document.querySelector('#form'));

axios.post("/api/xxx", {data: formData}).then(console.log).catch(console.error)

помните, что формат параметра postdata должен быть (url , FormData) , а не (url, {data: FormData})

beforeAll(function (done) {

          //parse form fields
          var parsefields = function(req,res){
            var form = new formidable.IncomingForm();
            form.parse(req, function (err, fields, files) {
              if (err) res.status(404).json(err)
              else res.status(200).json(fields);
            });  
          }

          router.route('parsefields').post(parsefields)

          //start server
          s = express()
          s.use('/',router)
          s.listen(4000,(err)=>{done(err)})
          done()
        });

        it('should parse and return form fields', function (done) {

          const fd = new FormData()
          fd.append('key','value')

          axios({
            method: 'POST',
            url: 'http://localhost:4000/parsefields',
            data: fd,
            headers : fd.getHeaders(),
          }).then(function (res) {
            expect(res).to.exist
            expect(res.body.key).to.equals('value')
          }).catch(err => {
            expect(err).not.to.exist
          })
          done()

        });
});

У меня такая же проблема. Получение 404 без ошибок. Использование formidable для парсера форм, экспресс и аксиом.

Я не знаю, поможет ли это кому-нибудь, но я видел эту проблему только в Safari и исправил ее с помощью formdata-polyfill . Safari должен изначально поддерживать FormData.append(), но, может быть, реализация немного отличается?

РЕДАКТИРОВАТЬ: я был неправ: я использовал URL-адрес, созданный из BLOB-объекта. Как только я начал использовать правильный блоб, все заработало как шарм!

У меня такая же проблема с Blob, пока я могу загрузить файл. Преобразование из BLOB-объекта в файл просто, но я хотел бы знать, является ли это ошибкой или я неправильно истолковал синтаксис:

`` js upload () { let data = new FormData() data.append('file', this.croppedFile) data.append('blob', this.croppedBlob, 'blob.jpeg') axios.post('/api/fp/process/', data, { headers: { 'Accept': текст/обычный`,
},
})

croppedFile is derived from croppedBlob with this simple code:
   `   return new File([this.cropImg], this.file.name, { type: this.file.type })`

Firefox dev tools show:

------WebKitFormBoundarytmInU7WtcHvmgYbc
Content-Disposition: данные формы; имя = «клякса»

------WebKitFormBoundarytmInU7WtcHvmgYbc
Content-Disposition: данные формы; имя="файл"; имя файла="dscn2950.jpg"
Тип содержимого: изображение/jpeg

блоб:http :// локальный:8080/9a6446d1-1ca2-4fd3-a6c8-8b36d863c146
------WebKitFormBoundarytmInU7WtcHvmgYbc--

```
Согласно документации mozilla formData.append , кажется, я мог бы использовать объекты Blob.

Что меня застряло, так это то, что мой сервер неправильно обрабатывал файлы, исправил это с помощью https://www.npmjs.com/package/multer .

это полезно для меня! Спасибо!

У меня ничего здесь не работало, потому что мой код был совершенно хорош.
Настоящая проблема была с файлом, который я перетаскивал из результатов поиска Windows — Chrome не смог найти реальное местоположение и сломал весь анализ FormData. Перейдите к файлу и перетащите его, чтобы решить проблему.

Всем привет,
Пожалуйста помогите.

POST https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart HTTP/1.1
Авторизация: носитель [YOUR_AUTH_TOKEN]
Content-Type: multipart/related; граница = foo_bar_baz
Длина контента: [NUMBER_OF_BYTES_IN_ENTIRE_REQUEST_BODY]

--foo_bar_baz
Тип содержимого: приложение/json; кодировка = UTF-8

{
"имя": "мойОбъект"
}

--foo_bar_baz
Тип содержимого: изображение/jpeg

[JPEG_ДАННЫЕ]
--foo_bar_baz--

axios не поддерживает составной/связанный тип запроса

Для меня это был (наверное) глоток. Потому что я получал ошибку с мини-файлами на моем сервере. Я вручную удалил все из папки dist, оставил тип содержимого неопределенным, и все работает как положено.
Таким образом, у вас будет что-то вроде:

formdata.append("selectPaymentType", $scope.extraFields.selectPaymentType);
formdata.append("pickupMethod", $scope.extraFields.selectPickupType);
пусть запрос = {
метод: «ПОСТ»,
URL: baseURL + «заказы»,
данные: формдата,
заголовки: {
«Тип контента»: не определено,
'x-токен доступа': $scope.userToken
}
};
$ http (запрос)
.успех (функция (г) {})
.ошибка (функция () {});

PS: Это отрывок... Я также прилагаю файлы и много других полей...

СЕРВЕР:

var form = new multiparty.Form({uploadDir: './uploads/orders/'});

form.parse (требование, функция (ошибка, поля, файлы) {
//ВАШ КОД ЗДЕСЬ
})

Привет, пожалуйста, мне нужна помощь: я получил «файл: это значение не должно быть пустым». когда я пытаюсь опубликовать изображение с помощью fetch :
handleSubmit = (event) => { event.preventDefault(); //const { category } = this.state; console.log(this.state.file) let formData = new FormData(); formData.append("file",this.state.file); formData.append("name",this.state.name); alert('You Added a new Category Named ' + this.state.file); fetch(`${process.env.REACT_APP_BASE_URL}/category/image`, { method: 'POST', body: formData }).then(res => res.json()).then(err => console.log(err)); } конструктор (реквизит) {
супер (реквизит);

this.state = {

    name: '',
    file: null
  ,
  isLoaded: false,
  isEditMode: false,

}

}
```

Для всех это сработало для меня.
Если вы используете входной файл, вы должны использовать MULTER в своем router.post('/') как промежуточное программное обеспечение, прежде чем получать другие поля ввода.

проверьте свой axios.create, эти заголовки должны быть "заголовки: {}" и не использовать данные. Вот так:
экземпляр var = axios.create({
заголовки: {
// 'Тип содержимого': 'application/x-www-form-urlencoded;charset=UTF-8',
},
// данные: {},
параметры: {}
});

По сей день это не работает на nodejs. Подход request-promise также сработал для меня.

Потратил 2 дня, пытаясь заставить это работать с axios в nodejs. Потратил 30 секунд, чтобы заставить его работать с запросом-обещанием в nodejs.

Я пробовал разные решения, но в конце концов решил эту проблему, добавив заголовки:

const FormData = require('form-data')
const axios = require('axios')

const form = new FormData()
form.append('foo', 'bar')

await axios.post('http://myserver', form, { headers: form.getHeaders() })

@ Гугрош Да. да. да.

Полдня потратил на выяснение, связано ли это с конфигурацией клиента или сервера.
В конце концов, headers: form.getHeaders() сделал свое дело.

Перешел на got , потому что он просто _работает_ с formData и multipart/form-data - https://github.com/sindresorhus/got 🙌
Близко, но нет сигарного Axios 👋

  const form = new FormData()
  const stream = fs.createReadStream(file.path)

  form.append('file', stream, file.name)

  try {
    await got.post('http://example.com', { body: form })
  } catch (error) {
    next(error)
  }

Вы можете сделать это следующим образом:
handleSubmit = (e: любой) => {
e.preventDefault();
константные данные = новые данные формы();
data.append('product_csv', this.state.csvfile);
пусть accessToken = localStorage.getItem('access_token');
аксиомы
.post('/загрузить', данные,
{ заголовки:
{ 'Content-Type': 'multipart/form-data', авторизация: accessToken }
})
.тог(рес => {
console.log('разрешение', разрешение);
});
};

@Googrosh Великолепно, .getHeaders() у меня тоже сработало. Я не могу сказать вам, сколько часов я потратил на это. Спасибо!

Я использую React Native. И я закончил эту проблему, используя rn-fetch-blob . Очень плохо :(

У меня такая же проблема, она просто не работает с простыми данными FormData без какого-либо файла, и .getHeaders() не помогает. Перемещено в «получил» библиотеку, которая просто работает. Упомянул это здесь также https://github.com/form-data/form-data/issues/458 (я использую Node v12)

2020 ES6 способ сделать

Имея форму в html, я привязывал данные так:

ДАННЫЕ:

form: {
   name: 'Joan Cap de porc',
   email: '[email protected]',
   phone: 2323,
   query: 'cap d\ou'
   file: null,
   legal: false
},

при отправке:

async submitForm() {
  const formData = new FormData()
  Object.keys(this.form).forEach((key) => {
    formData.append(key, this.form[key])
  })

  try {
    await this.$axios.post('/ajax/contact/contact-us', formData)
    this.$emit('formSent')
  } catch (err) {
    this.errors.push('form_error')
  }
}

См.: https://github.com/axios/axios/issues/789#issuecomment-508114703 .

На принимающей стороне, если вы используете Express, вам нужен multer . body-parser не обрабатывает запросы, состоящие из нескольких частей.

@DespertaWeb Не работает, когда нет файлов.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги