axios mengirim permintaan untuk mengirim data formulir


203

POSTpermintaan axios menekan url pada controller tetapi menetapkan nilai null ke kelas POJO saya, ketika saya pergi melalui alat pengembang di chrome, payload berisi data. Apa yang saya lakukan salah?

Permintaan POST Axios:

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

Respons Peramban:

masukkan deskripsi gambar di sini

Jika saya menetapkan header sebagai:

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

Permintaan melempar kesalahan

Kesalahan dalam memposting data multi bagian / formulir. Header Jenis-Konten tidak memiliki batas

Jika saya membuat permintaan yang sama pada tukang pos, itu berfungsi dengan baik dan menetapkan nilai untuk kelas POJO saya.

Adakah yang bisa menjelaskan cara menetapkan batas atau bagaimana saya bisa mengirim data formulir menggunakan aksioma.

Jawaban:


327

Anda dapat memposting data aksioma dengan menggunakan FormData () seperti:

var bodyFormData = new FormData();

Dan kemudian tambahkan bidang ke formulir yang ingin Anda kirim:

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

Jika Anda mengunggah gambar, Anda mungkin ingin menggunakan .append

bodyFormData.append('image', imageFile); 

Dan kemudian Anda dapat menggunakan metode posting aksioma (Anda dapat mengubahnya sesuai)

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

Anda dapat membaca lebih lanjut Di Sini


8
bodyFormData.set bukan fungsi yang saya dapatkan kesalahan ini
Manoj Bhardwaj

10
Anda harus menggunakan append sebagai ganti set.
Pratik Singhal

1
@ManojBhardwaj Anda harus mengikat fungsi, misalkan jika Anda membuat permintaan di dalam fungsi kirim Anda harus mengikat fungsi itu. mis: - onSubmit = {this.submit (bind (this)} atau ex: - di konstruktor konstruktor (super) {this.smitmit = this.submit.bind (this);} submit () {axios ({}) ; ...}
Srikanth Gowda

bodyFormData.append juga berfungsi untuk saya. tidak yakin mengapa settidak bekerja
Im Batman

1
Objek konfigurasi Anda salah. Seharusnya:{ method: 'post', url: 'myurl', data: bodyFormData, headers: {'Content-Type': 'multipart/form-data' } }
Steve Taylor

35

Lihat querystring .

Anda dapat menggunakannya sebagai berikut:

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

4
Ini bahkan lebih baik di lingkungan simpul
Jjagwe Dennis

Jika Anda memiliki objek bersarang di data Anda, 'querystring' mungkin tidak berfungsi seperti yang diharapkan. Dalam hal ini, Anda dapat menggunakan modul 'qs' untuk merangkai data.
Zihad Ul Islam

33

Dalam kasus saya, saya harus menambahkan batas ke header seperti berikut:

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

Solusi ini juga berguna jika Anda bekerja dengan React Native.


3
Ini memecahkan masalah saya ketika mencoba memposting ke api imgur. Tidak disebutkan di mana pun di dokumen, tetapi tanpa itu Anda mendapatkan respons URL 400 tidak valid.
Kolby

1
FormData._boundarytidak terdefinisi di Chrome 76 dan Firefox 67, dan axios tetap menghapus header Tipe Konten , jadi ini seharusnya tidak berpengaruh.
Ash

1
Bagian batas adalah satu-satunya hal yang hilang dari kode saya, bekerja dengan baik di simpul!
Rafael Moni

Anda adalah penyelamat hidup
Kevin RED

Hai, satu masalah meskipun ini hanya bekerja di android apakah Anda berhasil membuatnya bekerja di perangkat iOS?
Kevin RED

15

Unggah (banyak) file biner

Node.js

Hal menjadi rumit ketika Anda ingin memposting file melalui multipart/form-data, terutama banyak file biner. Di bawah ini adalah contoh kerja:

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()
})
  • Alih-alih headers: {'Content-Type': 'multipart/form-data' }saya lebih sukaheaders: formData.getHeaders()
  • Saya menggunakan asyncdan di awaitatas, Anda dapat mengubahnya menjadi pernyataan Janji sederhana jika Anda tidak menyukainya

Konten yang baru ditambahkan di bawah:

Browser

Browser FormDataberbeda dari paket-data NPM 'form-data'. Kode berikut berfungsi untuk saya di 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
Terima kasih banyak untuk contoh ini, mengalami kesulitan mencari tahu mengapa beberapa file unggahan tidak berfungsi.
Minkesh Jain

1
Saya bukan ahli, tetapi dalam kasus saya saya berhasil menghindari komplikasi ini ( concat-stream, asyncdan await) untuk mengunggah banyak file dengan menggunakan for(var x = 0; x<this.state.files.length; x++) { formData.append('files[]', this.state.files[x]) }sehingga saya bisa mengirimkan menggunakanaxios.post(url, formData, config)
laimison

@laimison terima kasih, ini bekerja untuk saya. Saya telah memperbarui jawaban saya.
Tyler Long

@ TylerLong Saya tidak bisa menemukan metode getHeaders di API FormData. developer.mozilla.org/en-US/docs/Web/API/FormData
ankur_rajput

9

Bahkan Lebih Mudah:

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

2
Ya, sepertinya, jika tidak ada unggahan file, ini adalah cara termudah.
Akalanka Weerasooriya

3

Menggunakan format aplikasi / x-www-form-urlencoded dalam aksioma

Secara default, aksioma serialisasi objek JavaScript ke JSON. Untuk mengirim data dalam format aplikasi / x-www-form-urlencoded, Anda dapat menggunakan salah satu opsi berikut.

Browser

Di browser, Anda dapat menggunakan API URLSearchParams sebagai berikut:

const params = URLSearchParams baru ();

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

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

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

Perhatikan bahwa URLSearchParams tidak didukung oleh semua browser (lihat caniuse.com), tetapi ada polyfill yang tersedia (pastikan untuk polyfill lingkungan global).

Atau, Anda bisa menyandikan data menggunakan perpustakaan qs:

const qs = membutuhkan ('qs');

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

Atau dengan cara lain (ES6),

impor qs dari 'qs';

data const = {'bar': 123};

opsi const = {

metode: 'POST',

header: {'tipe konten': 'application / x-www-form-urlencoded'},

data: qs.stringify (data),

url,};

aksioma (opsi);


3

2020 ES6 cara melakukan

Memiliki formulir dalam html saya diikat dalam data seperti:

DATA:

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

Metode di atas bekerja untuk saya tetapi karena itu adalah sesuatu yang sering saya butuhkan, saya menggunakan metode dasar untuk objek datar. Catatan, saya juga menggunakan Vue dan bukan REACT

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

Yang bekerja untuk saya sampai saya berlari ke struktur data yang lebih kompleks dengan objek dan file bersarang yang kemudian dibiarkan sebagai berikut

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 tidak terdefinisi dan formData dikembalikan di luar untuk, tetapi didefinisikan di dalam untuk. formData mudah, tetapi apa yang seharusnya objectToFormData?
Trevor

Saya pikir itu seharusnya nama fungsi. karena itu dimaksudkan untuk menjadi rekursif, jadi saya menganggap Anda dapat mengubah objectToFormDatake packageDataatau sebaliknya
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);
      });
  };
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.