axios post Anfrage zum Senden von Formulardaten


203

Die Axios- POSTAnforderung trifft die URL auf dem Controller, setzt jedoch Nullwerte für meine POJO-Klasse. Wenn ich Entwicklertools in Chrome durchlaufe, enthält die Nutzlast Daten. Was mache ich falsch?

Axios POST Anfrage:

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

Browser-Antwort:

Geben Sie hier die Bildbeschreibung ein

Wenn ich Header wie folgt setze:

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

Die Anfrage löst den Fehler aus

Fehler beim Posten von mehrteiligen / Formulardaten. In der Kopfzeile des Inhaltstyps fehlt die Grenze

Wenn ich dieselbe Anfrage beim Postboten mache, funktioniert sie einwandfrei und setzt Werte für meine POJO-Klasse.

Kann jemand erklären, wie man Grenzen setzt oder wie ich Formulardaten mit Axios senden kann.

Antworten:


327

Sie können Axios-Daten mithilfe von FormData () wie folgt veröffentlichen :

var bodyFormData = new FormData();

Fügen Sie dann die Felder zu dem Formular hinzu, das Sie senden möchten:

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

Wenn Sie Bilder hochladen, möchten Sie diese möglicherweise verwenden .append

bodyFormData.append('image', imageFile); 

Und dann können Sie die Axios-Post-Methode verwenden (Sie können sie entsprechend ändern).

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

Sie können mehr lesen Hier


8
bodyFormData.set ist keine Funktion, bei der dieser Fehler aufgetreten ist
Manoj Bhardwaj,

10
Sie müssen append anstelle von set verwenden.
Pratik Singhal

1
@ManojBhardwaj Sie müssen die Funktion binden. Nehmen wir an, wenn Sie eine Anfrage innerhalb der Submit-Funktion stellen, müssen Sie diese Funktion binden. Beispiel: - onSubmit = {this.submit (bind (this)} oder Beispiel: - im Konstruktor Konstruktor (super) {this.submit = this.submit.bind (this);} submit () {axios ({}) ; ...}
Srikanth Gowda

bodyFormData.append funktioniert auch für mich. set
ich

1
Ihr Konfigurationsobjekt ist falsch. Es sollte sein:{ method: 'post', url: 'myurl', data: bodyFormData, headers: {'Content-Type': 'multipart/form-data' } }
Steve Taylor

35

Überprüfen Sie den Querystring .

Sie können es wie folgt verwenden:

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

4
Dies ist noch besser in einer
Knotenumgebung

Wenn Ihre Daten verschachtelte Objekte enthalten, funktioniert "Querystring" möglicherweise nicht wie erwartet. In diesem Fall können Sie das Modul 'qs' verwenden, um die Daten zu stringifizieren.
Zihad Ul Islam

33

In meinem Fall musste ich die Grenze wie folgt zum Header hinzufügen :

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}`,
        },
    });

Diese Lösung ist auch nützlich, wenn Sie mit React Native arbeiten.


3
Dies löste mein Problem beim Versuch, auf imgurs API zu posten. Nirgendwo in den Dokumenten erwähnt, aber ohne sie erhalten Sie eine 400 ungültige URL-Antwort.
Kolby

1
FormData._boundaryist sowohl in Chrome 76 als auch in Firefox 67 undefiniert, und axios löscht den Content-Type-Header ohnehin , sodass dies keine Auswirkungen haben sollte.
Ash

1
Der Grenzteil war das einzige, was in meinem Code fehlte, funktionierte perfekt im Knoten!
Rafael Moni

Sie sind ein Lebensretter
Kevin RED

Hallo, ein Problem, obwohl dies nur unter Android funktioniert. Haben Sie es geschafft, dass es auf iOS-Geräten funktioniert?
Kevin RED

15

Laden Sie (mehrere) Binärdateien hoch

Node.js

Dinge werden kompliziert, wenn Sie Dateien über multipart/form-data, insbesondere mehrere Binärdateien, veröffentlichen möchten . Unten ist ein Arbeitsbeispiel:

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()
})
  • Anstelle von headers: {'Content-Type': 'multipart/form-data' }mir lieberheaders: formData.getHeaders()
  • Ich benutze asyncund awaithöher, Sie können sie in einfache Promise-Anweisungen ändern, wenn Sie sie nicht mögen

Neu hinzugefügter Inhalt unten:

Browser

Browser FormDataunterscheidet sich vom NPM-Paket 'Formulardaten'. Der folgende Code funktioniert für mich im Browser:

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
Vielen Dank für dieses Beispiel. Es fiel mir schwer herauszufinden, warum das Hochladen mehrerer Dateien nicht funktionierte.
Minkesh Jain

1
Ich bin kein Experte, aber in meinem Fall habe ich es geschafft, diese Komplikationen ( und ) beim Hochladen mehrerer Dateien zu vermeiden concat-stream, indem ichasyncawaitfor(var x = 0; x<this.state.files.length; x++) { formData.append('files[]', this.state.files[x]) }axios.post(url, formData, config)
laimison

@laimison danke, es funktioniert bei mir. Ich habe meine Antwort aktualisiert.
Tyler Long

@ TylerLong Ich kann keine getHeaders-Methode in der FormData-API finden. developer.mozilla.org/en-US/docs/Web/API/FormData
ankur_rajput

9

Noch einfacher:

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

2
Ja, wie es scheint, ist dies der einfachste Weg, wenn keine Dateien hochgeladen werden.
Akalanka Weerasooriya

3

Verwenden des Anwendungsformats / x-www-form-urlencoded in axios

Standardmäßig serialisiert axios JavaScript-Objekte in JSON. Um stattdessen Daten im Format application / x-www-form-urlencoded zu senden, können Sie eine der folgenden Optionen verwenden.

Browser

In einem Browser können Sie die URLSearchParams-API wie folgt verwenden:

const params = new URLSearchParams ();

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

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

axios.post ('/ foo', params);

Beachten Sie, dass URLSearchParams nicht von allen Browsern unterstützt wird (siehe caniuse.com), es jedoch eine Polyfüllung gibt (stellen Sie sicher, dass die globale Umgebung mehrfach gefüllt ist).

Alternativ können Sie Daten mithilfe der qs-Bibliothek codieren:

const qs = require ('qs');

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

Oder auf andere Weise (ES6),

qs aus 'qs' importieren;

const data = {'bar': 123};

const options = {

Methode: 'POST',

Header: {'content-type': 'application / x-www-form-urlencoded'},

Daten: qs.stringify (Daten),

url,};

Axios (Optionen);


3

2020 ES6 Vorgehensweise

Mit dem Formular in HTML habe ich Daten wie folgt eingebunden:

DATEN:

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

onSubmit:

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

Die obige Methode hat bei mir funktioniert, aber da ich sie oft brauchte, habe ich eine grundlegende Methode für flache Objekte verwendet. Beachten Sie, dass ich auch Vue und nicht REACT verwendet habe

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

Das hat bei mir funktioniert, bis ich auf komplexere Datenstrukturen mit verschachtelten Objekten und Dateien gestoßen bin, die dann auf Folgendes lauten

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 ist undefiniert und formData wird außerhalb des for zurückgegeben, aber innerhalb des for definiert. formData ist einfach, aber was soll objectToFormData sein?
Trevor

Ich denke, es soll der Name der Funktion sein. denn es sollte rekursiv sein, so dass ich nehme an, Sie das ändern können objectToFormDatazu packageDataoder umgekehrt
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);
      });
  };
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.