Axios: 'Content-Type': 'multipart / form-data'の.postを機能させることができません

作成日 2016年05月11日  ·  99コメント  ·  ソース: axios/axios

今日は、いくつかのパラメーターとアップロードする必要のあるファイルを使用してPOSTリクエストを処理するために数時間を費やしました。

純粋な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」バージョンは何でしょうか?

これが私の試みの1つです(単純なもの):

// 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でも解決しません。

これをデバッグするために他にできることがあれば教えてください。
Tks @nickuraltsev

Chrome Dev Toolsのネットワークパネルでリクエストがどのように表示されるかを確認し、可能であればスクリーンショットを提供してください。

@nickuraltsevは、これが役立つかどうかを確認します。

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

リクエストヘッダーが間違っていると思います。

では、リクエストペイロードはありませんか?

まあ、私たちは持っているべきですが、データは空の文字列として行きます。 何がそれを壊しているのかわかりません(最初の投稿で共有したコードを考慮して)。

そうですか。 また、開発ツールにはリクエストのリクエストペイロードセクションがありませんよね?

おそらく関連するヘッダーの問題。 content-typeがリクエストのconfigオブジェクトに設定されている場合、それは連結されます。
axios.post(
'https://example.com/login'、
{メールアドレス:メール、パスワード:hashedPassword}、
{ヘッダー:{'content-type': 'application / json'}}
);

ヘッダーのcontent-typeは、application / json、application / jsonとして入力されます
この場合、本体は解析されません

@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を別のオブジェクトでラップする代わりに、2番目の引数として追加できますか?
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)
})

エラー:終了後に書き込み

@krzkaczoraxiosでmultipart / form-dataを送信するための回避策を見つけましたか?

@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で同じ問題に直面しています。 request-promiseで使用したコードの要点を投稿できますか。

@ dan-boa here u go: https ://gist.github.com/krzkaczor/bdbe09d4096b051a3c18387c4ca79a06文字列をファイルとして送信する方法(パスの設定)のハックも示しています

誰かが疑問に思っている場合は、 FormDataaxiosで使用する方法の例を次に示します。 基本的に、データをバッファにストリーミングし、正しいヘッダーを渡す必要があります。

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呼び出しのデフォルトでは、FormData()リクエスト用に個別のaxiosインスタンスを作成できます)

別のリモートサーバーにアップロードしようとすると、ノード側でrequest-promiseを使用することになりました。

これと同じ理由で、request-promiseに切り替えました。 それ以外の場合はaxiosが大好きです!

@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()
  })
}))

または、promiseを使用します。

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投稿は、axiosv0.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インスタンスのデフォルトにデフォルトのデータパラメータが設定されている場合、上記のソリューションはいずれも機能しません。 また、AxiosインスタンスでデフォルトのContent-Typeヘッダーを指定しているかどうかを確認することもできます(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 = new FormData();
formData.append( 'name'、 '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回あることがわかりました。
Chromeのdevtoolをチェックインしましたが、リクエストはまだファイルと本文をペイロードで送信しています。
私はまだ理由を理解していませんが、私は解決策を持っています

それはリクエストヘッダーです。

`コード

    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を投稿しようとしています(これはEztext SMS APIです)
node.jsでaxiosを使用します。

次のコードに適しています。
新しいPromise(function(resolve、reject){を返す

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

しかし、SMSが送信されないため、axiosでは機能しませんが、次のリクエストのステータスコードは200になります:-
var axios = require( 'axios');

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

なぜPOSTリクエストはAxiosではなく 'request'ライブラリで成功するのですか?

ヘッダーを設定せずにデータを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もvanillajsもJSONデータをFormDataに変換しません。 AxiosはそれがFormDataであることを認識し、ヘッダーも設定するため、実際に設定する必要はありません。
私の以前の答えのヒントに従ってみてください...

@Iamuertepeluda
私はあなたの提案に従って次のことを試みましたが、運がありません、、、ステータス200 okを取得したのと同じ動作ですが、SMSは次の要求で送信されません
var axios = require( 'axios');

    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またはブラウザを使用していますか?

FormDataはネイティブであるため、ブラウザではconst FormData = require('form-data');は必要ありません。

さらに、ヘッダーとqsを設定せずに試すか、

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

私が言ったように、それはブラウザで自動的にヘッダーを設定する必要があります

@ Ruchi2729ノードを使用しているようです、ごめんなさい。
一度axiosでform-dataを使用したことを覚えていますが、実際に機能したかどうかは思い出せません。

しかし、これがeztextingでSMSを送信する正しい方法であると確信していますか? 彼らのドキュメントからは、APIキーと独自のノードクライアントを使用する必要があるように、それは異なっているようです...

これを再開できますか? 私を含め、まだ多くの人がこれにぶつかっているようです。 たとえば、このリクエストはaxios経由で期待どおりにサーバーに到達しませんが、Postman経由でmultipart/form-dataと同じファイルを送信すると、すべて機能します。

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

編集:私の問題は、base64でエンコードされたdata-uriをform-dataとして送信しようとしたことでした。 他の誰かが同じ問題に苦しんでいる場合は、それを変換するためのサンプルコードを次に示します。

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キーとすべてについてどのドキュメントを参照していますか?

@ Ruchi2729
申し訳ありませんが、別のSMSサービスでノード用の独自のクライアントがあるNexmoと混同しました😅

しかし、とにかく、あなたが参照したドキュメントによると、 formatjsonに設定し、axiosにJSONペイロードを送信させることでFormDataを回避できます(ペイロード形式によって暗黙的にヘッダーを推測させることができます)

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

私はこれにずっと長く苦労したことを認めたいので、うまくいけばこれが誰かを助けるでしょう。 axios、express、express-fileuploadを使用しています。 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);

フロントエンド(axios)

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')が空です。
私のコンポーネント

submitForm(){
this.formData = new FormData();
this.formData.append( 'file'、this。$ refs.file.files [0]);
this.formData.append( 'analysis'、this.analyticsForm.analysis);
this.formData.append( '_ method'、 'PATCH');
axios.post( '/ analytics'、
this.formData
、{headers:{'Content-Type': 'multipart / form-data'}})。then(response => this.isSubmittedRedirect(false、 '/ sources /' + this.source + '/ description' + '') )。
.catch((error)=> console.log(error))
}、

Content-Typeをmultipart/form-dataとして指定する必要があり、私がMicrosoftサイトの指示に従ってif (!Request.Content.IsMimeMultipartContent()) { throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType); }を確認してください: https ://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/sending-html-form-data-part-

私のファイルを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

そして、ここでさらに詳しく説明します: https ://stackoverflow.com/questions/47574218/converting-from-blob-to-binary-to-save-it-to-mongodb/49660839#49660839

次に、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]タグを使用してPost呼び出しのパラメーターとしてそれを使用します。

[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番目など)であり、サーバー側でファイルを処理する前に予想されるチャンクの総数を認識しています。 しかし、私は、あなたが何をしようとも、そのサイズのファイルでは、それがそのことをするのを待たなければならないと思います。 チャンク方式で行う場合も、メモリ管理に注意する必要があります。これは、毎回変数をクリアまたは再利用し、同じ変数の新しいバージョンを毎回再インスタンス化しないようにする必要があるためです。あなたはブロックをします。 グローバル変数が適切な数少ない回数の1つ、または実行ごとにモデルフィールドに設定するだけです。

@epferrariに同意します。この問題を再開することを検討してください。
ChromeのFormDataでbase64文字列を送信することは問題ありませんが、node(v8.9.3)のaxiosでは送信できません。
そしてそれはノードフェッチで動作します...

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はここからのものです。私が行っているのは、nodejsを使用してブラウザーのhttpリクエストをモックし、サーバーに画像を送信してリンクを取得することです。

私はこれを回避するために:

<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、{headers:{'Content-Type': 'multipart / form-data'}});

私も同じ問題を抱えてる

golangで動作していません

Vueで簡単な方法を見つけるだけですが、他の状況でも使用できると思います。😀
バックエンド:Express.jsおよびexpress-fileuploadパッケージ。

<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ヘッダーがreactjavaスクリプトから削除され、正常に機能しました。 以前は、コンテンツタイプを明示的に設定したときに境界が設定されていませんでした

編集:それについてさらに読んだ後、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つすべてが機能しませんでした。

2年後:
同じ問題...

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

これは間違いなく私にとってはうまくいきます—SafariiOSを含むすべてのブラウザ。

私のコードは次のようなものです:

関数samplePost(config){

// 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を呼び出してアップロードします

samplePost({

url: 'async',

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



// optionally include array of binary files

binaryFiles: thisFileList

});

差出人: AntonioVá[email protected]
送信日:2018年9月11日火曜日11:23 AM
宛先:axios / axios [email protected]
Cc:DavidRueter [email protected] ; コメント[email protected]
件名:Re:[axios / axios] 'Content-Type': 'multipart / form-data'の.postを機能させることができません(#318)

Safariからの投稿リクエストを行うために4時間とカウントします。 まだ起こっていない...一体何だ??

ここでの解決策はどれも私からはうまくいきませんでした... :(


コメントしたのでこれを受け取っています。
このメールに直接返信するか、GitHub https://github.com/axios/axios/issues/318#issuecomment-420371510で表示するか、スレッドhttps://github.com/notifications/unsubscribe-auth/AFbi6JQBv06LTwL4z3HIAlvXAXDyps1-をミュートします。 https://github.com/notifications/beacon/AFbi6BSPfwPvNaWPFSdvtLKRYXS1m4uKks5uZ_9wgaJpZM4Ibm_z.gif

これは私にとってもうまくいきました、 @ arviに感謝します

twiliosms = async(Codigo)=> {

var FormData = require( 'form-data');
var fs = require( 'fs');

var form = new FormData();
form.append( 'To'、 '+ 524772773737');
form.append( 'From'、 '+ 737373737');
form.append( 'Body'、Codigo);

試す {
axapi = axios(を待つ
{{
url: '2010-04-01 / Accounts / AC8aa53c907943af79234414bb725c2cd3 / Messages.json'、
baseURL: 'https://api.twilio.com'、
ヘッダー:{'content-type': multipart/form-data; boundary=${form._boundary} 、}、
データ:フォーム、
auth:{
ユーザー名: 'AC8aa53c907943af79234414bb725c2cd3'、
パスワード: *
}、
メソッド: 'post'、
}
)。

} catch(e){console.error(e)}
}

私はこのライブラリをさまよっていますが、フォームデータの投稿にはまだ自作の回避策が必要です。

すべてのアップデート?

NodeJS10.11.0とAxios0.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, {data: FormData}) (url , 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を受信します。 フォームパーサー、エクスプレス、アクシオスに手ごわいものを使用しています。

これが誰かに役立つかどうかはわかりませんが、この問題はSafariでのみ発生し、 formdata-polyfillを使用して修正しました。 SafariはFormData.append()をネイティブにサポートする必要がありますが、実装が少し異なる可能性がありますか?

編集:私は間違っていました:私はBlobから作成されたURLを使用していました。 正しいblobを使い始めると、すべてが魅力のように機能しました。

ファイルをアップロードできますが、Blobでも同じ問題が発生します。 BlobからFileへの変換は簡単ですが、これがバグなのか、構文を誤って解釈したのかを知りたいのですが。

`` 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': text / plain`、
}、
})

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:form-data; name = "blob"

------ WebKitFormBoundarytmInU7WtcHvmgYbc
Content-Disposition:form-data; name = "ファイル"; filename = "dscn2950.jpg"
コンテンツタイプ:image / jpeg

blob:http :// localhost: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]
コンテンツタイプ:マルチパート/関連; border = foo_bar_baz
コンテンツの長さ:[NUMBER_OF_BYTES_IN_ENTIRE_REQUEST_BODY]

--foo_bar_baz
コンテンツタイプ:application / json; charset = UTF-8

{{
"名前": "myObject"
}

--foo_bar_baz
コンテンツタイプ:image / jpeg

[JPEG_DATA]
--foo_bar_baz--

axiosはマルチパート/関連するリクエストタイプをサポートしていません

私にとって、それは(私が推測する)一口でした。 サーバー上の縮小ファイルでエラーが発生したためです。 distフォルダーからすべてを手動で削除し、コンテンツタイプを未定義のままにして、everythinggが期待どおりに機能するようにしました。
したがって、次のようなsthがあります。

formdata.append( "selectPaymentType"、$ scope.extraFields.selectPaymentType);
formdata.append( "pickupMethod"、$ scope.extraFields.selectPickupType);
リクエスト= {
メソッド: 'POST'、
url:baseURL + 'orders'、
データ:formdata、
ヘッダー:{
'Content-Type':未定義、
'x-access-token':$ scope.userToken
}
};
$ http(リクエスト)
.success(function(d){})
.error(function(){});

PS:これは抜粋です...私はファイルを添付し、さらに多くのフィールドを追加します...

サーバ:

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

form.parse(req、function(err、fields、files){
//ここにあなたのコード
})

hii plz私は助けが必要です:私は「ファイル:この値は空白であってはなりません」を取得しました。 フェッチを使用して画像をフェッチしようとすると、次のようになります。
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,

}

}
`` `

誰にとっても、これは私のために働いた。
入力ファイルを使用している場合は、他の入力フィールドを取得する前に、ミドルウェアのようにrouter.post( '/')でMULTERを使用する必要があります。

axios.createを確認してください。このヘッダーは「headers:{}」であり、data.likeを使用しないでください。
var instance = axios.create({
ヘッダー:{
// 'Content-Type': 'application / x-www-form-urlencoded; charset = UTF-8'、
}、
// データ: {}、
パラメータ:{}
});

今日まで、これはnodejsでは機能していません。 request-promiseアプローチも私のために働いた。

これをnodejsのaxiosで動作させるために2日間を費やしました。 nodejsのrequest-promiseで実際に機能させるために30秒を費やしました。

私はさまざまな解決策を試しましたが、最終的にはヘッダーを追加してこの問題を処理しました。

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

@Googroshはい。 はい。 はい。

それがクライアントまたはサーバーの構成に関連しているかどうかを理解するために半日を費やしました。
最後に、 headers: form.getHeaders()がトリックを行いました。

formDatamultipart/form-dataで_works_するだけなので、 gotに移動しました-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:any)=> {
e.preventDefault();
const data = new FormData();
data.append( 'product_csv'、this.state.csvfile);
accessToken = localStorage.getItem( 'access_token');
アクシオス
.post( '/ upload'、data、
{ヘッダー:
{'Content-Type': 'multipart / form-data'、Authorization:accessToken}
})
.then(res => {
console.log( 'res'、res);
});
};

@Googrosh Brilliant、 .getHeaders()も私のために機能しました。 これに何時間費やしたかはわかりません。 ありがとう!

私はreact-nativeを使用しています。 そして、私はrn-fetch-blobを使用してこの問題を解決しました。 残念な :(

同じ問題があります。ファイルがない単純なFormDataでは機能せず、.getHeaders()は役に立ちません。 動作する「got」libに移動しました。 ここでも言及しましたhttps://github.com/form-data/form-data/issues/458 (私はノードv12を使用しています)

2020ES6のやり方

htmlのフォームを使用して、次のようにデータをバインドしました。

データ:

form: {
   name: 'Joan Cap de porc',
   email: '[email protected]',
   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')
  }
}

参照: https ://github.com/axios/axios/issues/789#issuecomment -508114703

受信側でExpressを使用している場合は、 multer必要です。 body-parserは、マルチパートリクエストの解析を処理しません。

@DespertaWebファイルがない場合は動作しません。

このページは役に立ちましたか?
0 / 5 - 0 評価