axios розмістити запит для надсилання даних форми


204

POSTЗапит axios потрапляє на URL-адресу контролера, але встановлюючи нульові значення для мого класу POJO, коли я переглядаю інструменти розробника в хромі, корисне навантаження містить дані. Що я роблю неправильно?

Axios POST Запит:

var body = {
    userName: 'Fred',
    userEmail: 'Flintstone@gmail.com'
}

axios({
    method: 'post',
    url: '/addUser',
    data: body
})
.then(function (response) {
    console.log(response);
})
.catch(function (error) {
    console.log(error);
});

Відповідь веб-переглядача:

введіть тут опис зображення

Якщо я встановив заголовки як:

headers:{
  Content-Type:'multipart/form-data'
}

Запит видає помилку

Помилка в опублікуванні багаточастинних / форм-даних. В заголовку типу вмісту відсутня межа

Якщо я роблю такий же запит у листоноші, він працює нормально і встановлює значення для мого класу POJO.

Хто-небудь може пояснити, як встановити межу або як я можу надсилати дані форми за допомогою axios.

Відповіді:


331

Ви можете розміщувати дані axios, використовуючи FormData (), наприклад:

var bodyFormData = new FormData();

А потім додайте поля до форми, яку потрібно надіслати:

bodyFormData.set('userName', 'Fred');

Якщо ви завантажуєте зображення, можливо, захочете їх використовувати .append

bodyFormData.append('image', imageFile); 

І тоді ви можете скористатися методом axios post (Ви можете внести відповідні зміни)

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

Більше ви можете прочитати тут


8
bodyFormData.set не є функцією, я отримав цю помилку
Manoj Bhardwaj

10
Вам потрібно використовувати додаток замість встановленого.
Пратік Сінгал

1
@ManojBhardwaj вам потрібно прив’язати функцію, припустимо, якщо ур, який робить запит, всередині функції передати вам потрібно пов'язати цю функцію. ex: - onSubmit = {this.submit (bind (this)} або ex: - у конструкторі конструктора (super) {this.submit = this.submit.bind (this);} submit () {axios ({}) ; ...}
Шрікант Гоуда

bodyFormData.append працює і для мене. не впевнений, чому setне працює
Im Batman

1
Ваш об’єкт config невірний. Це повинно бути:{ method: 'post', url: 'myurl', data: bodyFormData, headers: {'Content-Type': 'multipart/form-data' } }
Стів Тейлор

35

Перевірте рядок запитів .

Ви можете використовувати його наступним чином:

var querystring = require('querystring');
axios.post('http://something.com/', querystring.stringify({ foo: 'bar' }));

4
Це ще краще в середовищі вузлів
Jjagwe Dennis

Якщо ви вклали об’єкти у свої дані, "рядок запитів" може працювати не так, як очікувалося. У такому випадку ви можете використовувати модуль 'qs' для строковування даних.
Зіхад Уль Іслам

33

У моєму випадку мені довелося додати межу до заголовка, як:

const form = new FormData();
    formData.append(item.name, fs.createReadStream(pathToFile));

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

Це рішення також корисне, якщо ви працюєте з React Native.


3
Це вирішило мою проблему при спробі опублікувати api в imgur. Ніде не згадується в документах, але без цього ви отримуєте відповідь 400 Недійсна URL-адреса.
Колбі

1
FormData._boundaryне визначено як у Chrome 76, так і в Firefox 67, і axios так чи інакше видаляє заголовок Content-Type , тому це не повинно мати жодного ефекту.
Еш

1
Прикордонна частина була єдиним, чого не було в моєму коді, працював досконало в вузлі!
Рафаель Моні

ти - рятівник життя
Джитін

Привіт, одна проблема, хоча це працює лише в android. Вам вдалося змусити її працювати на пристроях iOS?
Джитін

15

Завантажте (кілька) двійкових файлів

Node.js

Речі ускладнюються, коли ви хочете публікувати файли через них multipart/form-data, особливо декілька бінарних файлів. Нижче наведено робочий приклад:

const FormData = require('form-data')
const fs = require('fs')
const path = require('path')

const formData = new FormData()
formData.append('files[]', JSON.stringify({ to: [{ phoneNumber: process.env.RINGCENTRAL_RECEIVER }] }), 'test.json')
formData.append('files[]', fs.createReadStream(path.join(__dirname, 'test.png')), 'test.png')
await rc.post('/restapi/v1.0/account/~/extension/~/fax', formData, {
  headers: formData.getHeaders()
})
  • Замість цього headers: {'Content-Type': 'multipart/form-data' }я віддаю перевагуheaders: formData.getHeaders()
  • Я використовую asyncі awaitвище, ви можете змінити їх на прості обіцянки, якщо вони вам не подобаються

Щойно доданий вміст нижче:

Веб-переглядач

Огляд браузера FormDataвідрізняється від пакету NPM "форма-дані". У браузері для мене працює наступний код:

HTML:

<input type="file" id="image" accept="image/png"/>

JavaScript:

const formData = new FormData()

// add a non-binary file
formData.append('files[]', new Blob(['{"hello": "world"}'], { type: 'application/json' }), 'request.json')

// add a binary file
const element = document.getElementById('image')
const file = element.files[0]
formData.append('files[]', file, file.name)
await rc.post('/restapi/v1.0/account/~/extension/~/fax', formData)

1
Дякую вам за цей приклад, що важко було зрозуміти, чому завантаження декількох файлів не працює.
Мінкеш Джайн

1
Я не експерт, але в моєму випадку мені вдалося уникнути цих ускладнень ( concat-stream, asyncі await) для багаторазового завантаження файлів за допомогою for(var x = 0; x<this.state.files.length; x++) { formData.append('files[]', this.state.files[x]) }так що я можу уявити , використовуючиaxios.post(url, formData, config)
laimison

@laimison дякую, це працює для мене. Я оновив свою відповідь.
Тайлер Лонг

@TylerLong Я не можу знайти жодного методу getHeaders в API FormData. developer.mozilla.org/en-US/docs/Web/API/FormData
ankur_rajput

9

Ще простіше:

axios.post('/addUser',{
    userName: 'Fred',
    userEmail: 'Flintstone@gmail.com'
})
.then(function (response) {
    console.log(response);
})
.catch(function (error) {
    console.log(error);
});

2
Так, як здається, якщо немає завантажень файлів, це найпростіший спосіб.
Akalanka Weerasooriya

3

Використання формату application / x-www-form-urlencoded в аксіосах

За замовчуванням axios серіалізує об’єкти JavaScript в JSON. Для того, щоб надіслати дані у форматі application / x-www-form-urlencoded, ви можете скористатися одним із наступних варіантів.

Веб-переглядач

У веб-переглядачі ви можете використовувати API URLSearchParams наступним чином:

const params = новий URLSearchParams ();

params.append ('param1', 'value1');

params.append ('param2', 'value2');

axios.post ('/ foo', парами);

Зауважте, що URLSearchParams підтримується не в усіх браузерах (див. Caniuse.com), але є поліфіл (переконайтеся, що це заповнює глобальне середовище).

Крім того, ви можете кодувати дані за допомогою бібліотеки qs:

const qs = вимагати ('qs');

axios.post ('/ foo', qs.stringify ({'bar': 123}));

Або іншим способом (ES6),

імпорт qs з 'qs';

const data = {'bar': 123};

параметри const = {

метод: 'POST',

заголовки: {'content-type': 'application / x-www-form-urlencoded'},

дані: qs.stringify (дані),

url,};

аксіоз (варіанти);


3

2020 спосіб ES6

Маючи форму в HTML, я пов'язував такі дані:

ДАНІ:

form: {
   name: 'Joan Cap de porc',
   email: 'fake@email.com',
   phone: 2323,
   query: 'cap d\ou'
   file: null,
   legal: false
},

onPubmit:

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')
  }
}

1

Вищеописаний метод працював для мене, але оскільки це було те, що мені часто потрібно, я використовував основний метод для плоского об'єкта. Зауважте, я також використовував Vue, а не REACT

packageData: (data) => {
  const form = new FormData()
  for ( const key in data ) {
    form.append(key, data[key]);
  }
  return form
}

Що працювало для мене, поки я не зіткнувся з більш складними структурами даних з вкладеними об'єктами та файлами, які потім перейшли до наступного

packageData: (obj, form, namespace) => {
  for(const property in obj) {
    // if form is passed in through recursion assign otherwise create new
    const formData = form || new FormData()
    let formKey

    if(obj.hasOwnProperty(property)) {
      if(namespace) {
        formKey = namespace + '[' + property + ']';
      } else {
        formKey = property;
      }

      // if the property is an object, but not a File, use recursion.
      if(typeof obj[property] === 'object' && !(obj[property] instanceof File)) {
        packageData(obj[property], formData, property);
      } else {
        // if it's a string or a File
      formData.append(formKey, obj[property]);
      }
    }
  }
  return formData;
}

objectToFormData не визначено, а formData повертається за межі for, але визначається всередині for. formData - це легко, але яким повинен бути об’єктToFormData?
Тревор

Я думаю, що її повинна бути назва функції. тому що це повинно бути рекурсивним, тому я припускаю, що ви можете змінити objectToFormDataна packageDataабо навпаки
Raymond Ativie

0
import axios from "axios";
import qs from "qs";   

const url = "https://yourapplicationbaseurl/api/user/authenticate";
    let data = {
      Email: "testuser@gmail.com",
      Password: "Admin@123"
    };
    let options = {
      method: "POST",
      headers: { "content-type": "application/x-www-form-urlencoded" },
      data: qs.stringify(data),
      url
    };
    axios(options)
      .then(res => {
        console.log("yeh we have", res.data);
      })
      .catch(er => {
        console.log("no data sorry ", er);
      });
  };
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.