error when putting formdata to api gateway aws - reactjs

Bit strange to get " access to fetch URL blocked by cors preflight etc..." because the PUT request works for me in postman but i only get that error when i try to upload in react js . Here is my code above.
I get another error by the way "
error TypeError: Failed to fetch
at Upload (Upload.js:28:1)
Which i have no clue why i am getting a type error . Any help would be appreciated
import axios from 'axios';
import React,{Component} from 'react';
import { useState } from 'react';
export default function Upload(){
const [data,setData] = useState()
if (data) {
const file = (data.target.files[0])
console.log(file)
const myHeaders = new Headers();
myHeaders.append("Content-Type", "image/jpeg");
const formdata = new FormData();
formdata.append('File', file);
const requestOptions = {
method: 'PUT',
headers: myHeaders,
body: formdata,
redirectXXX: 'manual'
};
fetch("https://XXXX.execute-api.us-east-1.amazonaws.com/prod/XXXX/IMG_0733.jpg", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
}
return (
<div>
<form>
<input type="file" onChange={(e) => setData(e)}/>
</form>
</div>
)
}
expecting upload to put into API same way the postman does it.,

Related

How to get the response data by using react-query useMutation and axios post method?

I'm trying to get the data from a axios post methed.
I can get it by only using axios.
I cannot figure out why using the react-query useMutation console log the response data is undefined.
api/index.js
export const postCreateMeetingId = async (token) => {
await axios.post('http://localhost:3001/create-meeting/', {token:`${token}`}, {
headers: {
"Content-Type": "application/json",
authorization: `${token}`,
},
})
.then((res) => {
console.log(res.data) //successfully got the data here
return res.data
})
}
pages/meetingRoom.js
var token='my token is here'
export default function MeetingRoom(){
const {mutate, data} = useMutation(postCreateMeetingId, {
onSuccess: async (res) => {
console.log(res) //undefined
console.log(data) //undefined
}
})
const getMeetingAndToken = async () => {
return mutate(token)
}
return(
<div>
<button onClick={getMeetingAndToken}>get</button>
</div>
);
}
I wish to know how to get the response data by using useMutation so that I could throw this data to another post api.

ReactJS: POST 400 (Bad Request) using Axios

I am using axios to hit an API to upload a .apk file onto a 3rd party app which is running locally on my computer. Using the API on Postman is giving the desired result but while integrating it with my React app I am getting POST http://localhost:8000/api/v1/upload 400 (Bad Request) error.
I have the following with structure:
src/httpRequest.js
import axios from "axios";
export default axios.create({
baseURL: "http://localhost:8000",
headers: {
"Content-type": "application/json",
Authorization: <API_KEY>
}
});
src/services/Upload.js
import http from "../httpRequest";
const upload = (file, onUploadProgress) => {
const formData = new FormData();
formData.append("file", file);
return http.post("/upload", formData, {
headers: {
"Content-Type": "multipart/form-data",
Authorization:
<API_KEY>
},
onUploadProgress,
});
};
export default {
upload,
};
src/components/ApkUpload.js
import React, { useState, useEffect } from 'react';
import axios from 'axios';
const ApkUpload = () => {
const [selectedFiles, setSelectedFiles] = useState(undefined);
// eslint-disable-next-line no-unused-vars
const [currentFile, setCurrentFile] = useState(undefined);
const [progress, setProgress] = useState(0);
const [message, setMessage] = useState('');
const [fileDetails, setFileDetails] = useState([]);
const handleUpload = async () => {
const data = new FormData();
data.append('file', selectedFiles);
try {
const res = await axios.post('http://localhost:8000/api/v1/upload', data, {
headers: {
'Content-Type': 'multipart/form-data',
Authorization: <API_KEY>,
},
onUploadProgress: (progressEvent) => {
setProgress(parseInt(Math.round((progressEvent.loaded * 100) / progressEvent.total), 10));
},
});
} catch (err) {
if (err.response.status === 500) {
setMessage('There was a problem with the server');
} else {
setMessage(err.response.data.message);
}
}
};
const handleChange = (e) => {
setSelectedFiles(e.target.files);
setCurrentFile(e.target.files[0]);
};
useEffect(() => {
axios.get("http://localhost:8000/api/v1/scans", {
headers: {
Authorization:
<API_KEY>,
},
}).then(res => {
setFileDetails(res.data.content);
});
},[]);
return (
<div className="container">
// simple button calling above methods
</div>
);
};
export default ApkUpload;
I am using MobSF as my third party app and for upload they require multipart/form-data.
While using postman I was able to get the desired result but I'm not able to do so with my frontend. Any help regarding this issue will be highly appreciated!
const data = new FormData();
data.append('file', selectedFiles[0]);
Inside your handleUpload function selectedFiles state is of type FileList but it should be File.
If you are handling single file then you can use:
data.append('file', selectedFiles[0]);
For multiple files you can do:
for(let i=0;i<selectedFiles.length;++i){
data.append('file',selectedFiles[i])
}

Unable to upload file from react to laravel using react hook form and ajax

Up to this point a file can be viewed on input:
export async function store(input) {
console.log("input", input);
return httpClient.post(`${apiEndpoint}`, input);
}
On above console.log, it shows data as:
But, on the serverside laravel, if I print_r($request->all()) it shows data as:
My http client looks like this:
import axios from "axios";
const apiURL = process.env.MIX_SPA_URL;
axios.defaults.headers.common["Content-Type"] = "application/json";
axios.defaults.headers.common["X-Requested-With"] = "XMLHttpRequest";
axios.defaults.withCredentials = true;
let client = axios.create({
baseURL: apiURL,
});
axios.interceptors.response.use(null, (error) => {
const expectedError =
error.response &&
error.response.status >= 400 &&
error.response.status < 500;
if (!expectedError) {
console.log("error from httpClient >>", error);
}
return Promise.reject(error);
});
function setJwt(token) {
client.defaults.headers.common["Authorization"] = "Bearer " + token;
}
const httpClient = {
get: client.get,
post: client.post,
put: client.put,
delete: client.delete,
setJwt,
};
export default httpClient;
Also, in case if you want to look how I have created input file using react-hook-form as:
<input
className={`form-control w-full ${
errors["cover_image"] ? "border-red-500" : ""
}`}
type="file"
{...register("cover_image")}
/>
Why are the images not being sent to the server?
In case of laravel, I am using laravel sanctum in combination with fortify. And, the middleware added for this route are auth:sanctum and verified.
Also, I have tried by adding headers as: "Content-Type": "multipart/form-data",
export async function store(input) {
console.log("input", input);
return httpClient.post(`${apiEndpoint}`, input, {
headers: {
"Content-Type": "multipart/form-data",
},
});
}
But, with this header, not a single data got send to the server. Here, is the screenshot:
I think you must put your file in formData and then pass it as your post request data
export async function store(input) {
const formData = new FormData();
formData.append("cover_image", input.cover_image[0]);
formData.append("blockchain", input.blockchain);
formData.append("description", input.description);
formData.append("name", input.name);
return await httpClient.post(`${apiEndpoint}`, formData, {
headers: {
"Content-Type": "multipart/form-data",
},
});
}

Sending .wav file from React frontend to Flask backend

I am quite new new Flask and Blobs in general, but I've been trying for some time to send a .wav file from my frontend to my backend. In general it seems like I should put the file into a FormData(), and send a post-request to the backend.
Here is my frontend code:
import React from "react";
import { DropzoneArea } from "material-ui-dropzone";
import axios from "axios";
const DropzoneAreaExample = () => {
const headers = {
"content-type": "multipart/form-data",
};
const fileDrop = (files: File[]) => {
const formData = new FormData();
const file: File = files[0];
formData.append("file", file);
axios
.post("http://localhost:5000/analyze", { formData }, { headers })
.then((res) => console.log(res.data));
};
return (
<div>
<DropzoneArea onDrop={fileDrop} />
</div>
);
};
export default DropzoneAreaExample;
And on the backend I am trying this:
import flask
from flask import request
from flask_cors import CORS
app = flask.Flask(__name__)
CORS(app)
#app.route('/analyze', methods=['GET', 'POST'])
def analyze_data():
if request.method == 'POST':
f = request.files['file']
f.save()
return "test"
Any help or nudge in the right direction would be much appreciated!
When you pass the data to Axios post as the second parameter, you do not put it in an object.
axios
.post("http://localhost:5000/analyze", formData, { headers })
.then((res) => console.log(res.data));
I finally found a solution. The problem was in the axios-request. I transformed it to a fetch-request, and then everything worked out. Here's the working request from the frontend:
const FileUploader = () => {
const fileDrop = (files: File[]) => {
const formData = new FormData();
const file: File = files[0];
formData.append("file", file);
fetch("http://localhost:5000/upload", {
method: "POST",
body: formData,
}).then((res) => {
console.log(res.text);
});
};

React axios file upload failing - error "Multipart: Boundary not found"

My code isn't working as it should, it keeps receiving a 400 from the server and failing to upload. I must be making mistakes in the react component so please can you take a look for me? All's working in Postman, so the backend code seems fine.
import React, { useState } from "react";
import axios from "axios";
const UploadAvatar = () => {
const [image, setImage] = useState();
const handleUpload = async (e) => {
e.preventDefault();
const config = {
headers: {
"content-type": "multipart/form-data",
Authorization: localStorage.getItem("token"),
},
};
try {
const formData = new FormData();
formData.append("avatar", image);
const response = await axios.post(
"/users/me/avatar",
{ formData },
config
);
console.log(response);
} catch (err) {
console.error(err.message);
}
};
return (
<div>
<form onSubmit={handleUpload}>
Select image to upload:
<input
type="file"
onChange={(e) => setImage(e.target.value)}
name="fileToUpload"
/>
<input type="submit" value="Upload Image" name="submit" />
</form>
</div>
);
};
export default UploadAvatar;
There some things you need to do.
This is not related to the problem, but I think it is worth checking:
const config = {
headers: {
"content-type": "multipart/form-data",
Authorization: localStorage.getItem("token"),
},
}
What scheme is your Authorization (Basic, Bearer, OAuth)?
. If its a Bearer schema (e.g.), is your localStorage.getItem("token") returning only the token or is returning "Bearer {token}"? For bearer token, you need to include the word 'Bearer' before the token.
The content-type it's not really necessary here, but you can let it there if you prefer.
In your code, you need to do some changes:
In your handleUpload you need to do this:
try {
const formData = new FormData();
formData.append("avatar", image);
// I just removed the curly brackets from formData
const response = await api.post("/users/me/avatar", formData, config);
console.log(response);
} catch (err) {
console.error(err.message);
}
And in your input file type:
<input
type="file"
onChange={(e) => setImage(e.target.files[0])}
name="fileToUpload"
/>
For input file types, the target should be e.target.files, wich returns a list of files and each file is a FileList object. As you sending only one image you can set it as e.target.files[0] to get the first image.
And that´s all. It should work now! :)
I did a poc here and everything goes ok.
for bad request
it happens because of axios ,
your not sending json data
in your code
const response = await axios.post(
"/users/me/avatar",
{ formData },<---------here is the problem object
formData ,<-------try without curly brazes or use below detailed axios
config
);
console.log(response);
} catch (err) {
console.error(err.message);
}
};
change axios
axios({
method: 'post',
url: 'myurl',
data: formData ,
headers: {'Content-Type': 'multipart/form-data' }
})
.then(function (response) {
//handle success
console.log(response);
})
.catch(function (response) {
//handle error
console.log(response);
});
another problem
YOUR SENDING FILES
<input
type="file"
onChange={(e) => setImage(e.target.value)}<-------wrong e.target.files[0]
name="fileToUpload"
/>
change
if u sending mutliple files
e.target.files
or if you sending single file use
e.target.files[0]
change code
<input type="file"
onChange={(e) => setImage(e.target.files[0])}
name="fileToUpload"
/>

Resources