フォームデータを送信するaxios postリクエスト


203

axios POSTリクエストがコントローラーのURLにヒットしていますが、POJOクラスにnull値を設定しています。Chromeの開発者ツールを実行すると、ペイロードにデータが含まれています。何が悪いのですか?

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

リクエストはエラーをスローします

multipart / form-dataの投稿中にエラーが発生しました。Content-Typeヘッダーに境界がありません

私が郵便配達員で同じリクエストを出すと、それはうまくいき、私のPOJOクラスに値を設定します。

誰でも境界を設定する方法や、axiosを使用してフォームデータを送信する方法を説明できますか?

回答:


327

次のようにFormData()を使用してaxiosデータを投稿できます 。

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
セットの代わりに追加を使用する必要があります。
Pratik Singhal

1
@ManojBhardwaj関数をバインドする必要があります。サブミット関数内でリクエストを作成する場合、uがその関数をバインドする必要があるとします。ex:-onSubmit = {this.submit(bind(this)}またはex:-コンストラクターコンストラクター(super){this.submit = this.submit.bind(this);} submit(){axios({}) ; ...}
Srikanth Gowda

bodyFormData.appendも私のために働いています。わからないなぜset動作しない
イムバットマン

1
設定オブジェクトが間違っています。これは以下のようになります{ method: 'post', url: 'myurl', data: bodyFormData, headers: {'Content-Type': 'multipart/form-data' } }
スティーヴ・テイラー

35

querystringを確認してください。

次のように使用できます。

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

4
これはノード環境ではさらに優れています
Jjagwe Dennis

データにネストされたオブジェクトがある場合、「querystring」は期待どおりに機能しない可能性があります。その場合、「qs」モジュールを使用してデータを文字列化できます。
Zihad Ul Islam

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
これにより、imgurのapiに投稿しようとしたときに私の問題が解決しました。ドキュメントのどこにも言及されていませんが、それがないと400 Invalid URL応答が返されます。
コルビー

1
FormData._boundaryはChrome 76とFirefox 67の両方で未定義であり、axiosはとにかくContent-Typeヘッダーを削除するため、これは効果がないはずです。
Ash

1
境界部分は私のコードに欠けていた唯一のものであり、ノードで完全に機能しました!
Rafael Moni

あなたは人生の救世主です
ケビン・レッド

こんにちは、これはAndroidでのみ機能しますが、iOSデバイスでも機能させることができましたか?
Kevin RED

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ますが、気に入らない場合はプレーンなPromiseステートメントに変更できます

以下に新しく追加されたコンテンツ:

ブラウザ

ブラウザーFormDataは、NPMパッケージ「form-data」とは異なります。次のコードはブラウザで私のために働きます:

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
この例をありがとうございました。なぜ複数のファイルのアップロードが機能しないのか理解するのに苦労しました。
Minkesh Jain

1
私は専門家ではないんだけど、私の場合、私はこれらの合併症(避けるために管理しているconcat-streamasyncawait使用して複数ファイルのアップロードのための)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 FormData APIでgetHeadersメソッドが見つかりません。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

axiosでapplication / x-www-form-urlencoded形式を使用する

デフォルトでは、axiosはJavaScriptオブジェクトをJSONにシリアル化します。代わりにapplication / x-www-form-urlencoded形式でデータを送信するには、次のいずれかのオプションを使用できます。

ブラウザ

ブラウザでは、次のようにURLSearchParams APIを使用できます。

const params = new URLSearchParams();

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

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

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

URLSearchParamsはすべてのブラウザー(caniuse.comを参照)でサポートされているわけではありませんが、利用可能なポリフィルがあります(必ずグローバル環境をポリフィルしてください)。

または、qsライブラリを使用してデータをエンコードすることもできます。

const qs = require( '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(data)、

url、};

axios(オプション);


3

2020 ES6のやり方

htmlのフォームを持つと、次のようにデータにバインドされます。

データ:

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

上記の方法でうまくいきましたが、頻繁に必要になるため、平面オブジェクトの基本的な方法を使用しました。注、私も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は簡単ですが、objectToFormDataはどうあるべきですか?
Trevor

関数の名前だと思います。それは再帰的であることを意図しているので、私はあなたがobjectToFormDatapackageDataまたはその逆に変更できると思います
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);
      });
  };
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.