I'm trying to upload a CSV File from React to my Flask backend. My code is shown below. With the code below, the Flask returns 400 (Axios Error).
When I change the Flask to print(request.files)
, it prints ImmutableDict([])
and it doesn't seem to have any data (I think so..)
Error:
AxiosError {message: 'Request failed with status code 400', name: 'AxiosError', code: 'ERR_BAD_REQUEST', config: {…}, request: XMLHttpReques
App.js:
let handleSubmit = async (e) => {
e.preventDefault()
let file = csvFile
const formData = new FormData()
formData.append("file", file)
axios
.post("http://127.0.0.1:5000/reactTest", formData)
.then((res) => console.log(res))
.catch((err) => console.warn(err))
...
<input
type='file'
value={csvFile}
name='csvFile'
/>
<button type='submit' onClick={handleSubmit}></button>
api.py:
@app.route('/reactTest', methods=['POST'])
def reactTest():
if request.method == 'POST':
# print(request.files)
print(request.files['file'])
return {'status': 200}
CodePudding user response:
<input type="file">
cannot be a controlled component because you cannot set the value
due to browser security restrictions.
Instead, treat it as an uncontrolled component. You can even just pass an HTMLFormElement
into FormData
to capture all inputs.
const [hasFiles, setHasFiles] = useState(false);
const handleSubmit = async (e) => {
e.preventDefault();
const formData = new FormData(e.target); // pass the entire form
try {
console.log(await axios.post("http://127.0.0.1:5000/reactTest", formData));
} catch (err) {
console.warn(err.toJSON());
}
};
return (
<form onSubmit={handleSubmit}>
<input
type="file"
name="file"
onChange={(e) => setHasFiles(e.target.files.length > 0)}
/>
<button type="submit" disabled={!hasFiles}>
Submit
</button>
</form>
);
Note the file input's name is now "file" to match the field you want in FormData
.
CodePudding user response:
To get the files of an input. You need to use (note you need to specify the input index):
let file = e.target[0].files
If you want get a dict instead of imutable dict, use 'to_dict()'
request.files['file'].to_dict()
CodePudding user response:
You need to specify Content-Type: multipart/form-data
header for the request to be recognized as containing file:
let handleSubmit = async (e) => {
e.preventDefault()
let file = e.target.files[0];
const formData = new FormData()
formData.append("file", file)
axios
.post("http://127.0.0.1:5000/reactTest", formData, {
headers: {
'Content-Type': 'multipart/form-data'
})
.then((res) => console.log(res))
.catch((err) => console.warn(err))
...