2017-11-07 12 views
0

初めてファイルをアップロードする機能を設定しています。私は反応フロントエンドとファイルを格納するエクスプレスサーバーがあります。私はそれを設定して、ユーザーがファイルを提出できるようにして、それをエクスプレスサーバーに保存したいと思うように保存します。しかし、ユーザーがフォームを送信するたびに、反応フロントエンド(ポート3000上)からサーバー上のPOSTルート(ポート3050)にリダイレクトされます。私はこれがポストリクエストのデフォルトの振る舞いであったことを知らなかった。フォーム送信(React、Express、Multer)によるファイルアップロードのリダイレクトの防止

私はこの動作を避けたいと思っていますが、これを実行する最善の方法が不明です。私はAXIOSリクエストとして機能するアクションを構築しようとしましたが、AXIOSリクエストでフォームデータ(特にファイルデータ)にアクセスするのに問題があります。私の理解は、AXIOSにマルチパートフォームデータのネイティブサポートがないことです。

Event.preventdefaultは明白な選択ですが、それを実装すると、フォーム送信が停止し、適切なフォームデータを取得してから送信します。

フォームのコードが以下に含まれています(このバージョンでは、イベントのデフォルトを防ぎ、アクションをディスパッチするオンクリックイベントが使用されています - アクションは発生しますが、

 <div className="modal-wrapper"> 
      <h3 className="title__h3">Upload Data</h3> 
      <p>Drag and drop anywhere or choose a file to upload.</p> 
      <p>.csv or .xlsx</p> 
      <form className="upload-form" ref="uploadForm" id="uploadForm" action="http://localhost:3050/upload" method="POST" enctype="multipart/form-data"> 
       <input name="fileName" placeholder="Name the file you're uploading here"/> 
       <input type="file" name="upl" id="file" className="inputfile" /> 
       <label htmlFor="file" className="btn btn__white-outline btn__full-width">Select a File</label> 
       <input onClick={this.submitForm} type="submit" value="submit" /> 
      </form> 
     </div>; 

私の簡単なMulterルート:

app.post('/upload', upload.single('upl'), function(req,res,next) { 
    return false 
}) 

私の理解では、Axiosを通じてマルチパート形式のアイテムを送信するためのネイティブサポートがないことである、私は中にいるFormDataモジュールに引っ張って避けたいのですがフォーム(他のtハンはリダイレクト)完璧に動作します。フォームデータを送信しながらフォームがサーバー側のページを読み込まないようにする簡単な解決法はありますか?

答えて

1

submitFormハンドラでは、イベントへの参照を渡し、event.preventDefault()を使用します。

submitForm(event) { 
     event.preventDefault(); 
     ...other code here... 
    } 

また、ここで

<form className="upload-form" ref="uploadForm" id="uploadForm" action="http://localhost:3050/upload" method="POST" enctype="multipart/form-data" onSubmit={ (event) => { event.preventDefault(); } }> 
+0

どちらもうまくいく、あなたの選択を取る。 –

+0

助けてくれてありがとう。私が実行している問題は、リクエストを別の関数(あなたの例では '...他のコードはここに...')で送信することですが、Axiosを使用する必要があります。私は最後の数時間Axiosを介してreq.fileを送信する方法を理解しようとしており、協力することができませんでした。しかし、Axiosなしでフォームを送信すると、ページの更新以外に完璧な処理が実行されます。リフレッシュせずにバニラフォームをエミュレートできるコマンドがあることを期待していましたが、Axiosを放棄しなければならないかもしれません。 –

+0

Axiosでのファイルアップロードの処理については、以下を参照してください。有益な回答を投票するのを忘れないでください... –

0

フォームのonSubmit属性のサブミットを処理する、onSubmit="{this.handleSubmit}"のメソッドを作成し、データを非同期で送信します。

+0

私はこの問題をさらに詳しく調査してきたため、ファイルデータを非同期的にポストするのに問題があることが明らかになりました。 AXIOSを使用して私の投稿要求をすべて行ってきましたが、サーバーが適切に保存するためにファイルを含むrequest.fileを送信する良い方法を見つけることができませんでした。私はそれを切り替えて、要求本体からファイルを保存しようとしましたが、[object Object]以外のものとして渡すことができませんでした。要するに、あなたのソリューションは正しいですが、使用しているツールで機能する非同期ポストを作成するのに問題があります。 –

+0

@SadBonesMalone申し訳ありませんが、私はあなたの質問に答えたときに急いでいた、私はいくつかのものをやり遂げるだろうと私は答えに詳細になります(誰もあなたに既に答えていない場合) – StormRage

+0

心配しないでください!私はすぐに私の答えに追加する解決策を考え出しました。ご協力いただきありがとうございます。 –

0

を試すことができます私はhandleChange方法が<input type="file" onChange={this.handleChange} />

のonChangeイベントに関連付けられていAxios

handleChange = (event) => { 
    const fileReader = new FileReader(); 
    const fileToUpload = event.target.files[0]; 

    fileReader.onload = (upload) => { 
     const allFiles = [ ...this.state.allFiles ].concat(upload.target.result); 

     this.setState({ 
      allFiles 
     }); 
    }; 

    fileReader.readAsDataURL(fileToUpload); 
}; 

のファイルを提出処理する方法でありますその後、フォーム送信ハンドラ

handleSubmit = (event) => { 
    event.preventDefault(); //So the page does not refresh 
    const { allFiles } = this.state; 
    const Promises = []; 

    allFiles.forEach(file => { 
     Promises.push(Axios({ 
      url: "a url goes here", 
      method: "POST", 
      data: { 
       file: file, //This is a data url version of the file 
      } 
     }));  
    }); 

    Axios.all(Promises).then(result => { 
     alert(result.message); //Display if it uploaded correctly 
    }) 
}; 
関連する問題