My fetch doesn't upload the JSON string, I can't see the error in my code - reactjs

I'm using Slim v4 for my REST API for testing purposes.
I want to fetch a JSON Data string to my REST API for saving some events.
public async callSaveEvent(event: EventList) {
let url: string = config.basePath + "eventList/saveEventList";
console.table(JSON.stringify(event));
await fetch(url, {
method: 'POST',
mode: 'no-cors',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ event })
}).then(response => {
if (!response.ok) {
throw new Error("Something is bad");
}
}).catch(error => {
console.error("Das ist passiert!: ", error);
});
}
This is my current Code. If I use the fetch.options.mode == "cors", I recieve in Slim that this Method is not allowed. Method is OPTIONS instead of POST. Because of this I using mode == "no-cors".
$param = $req->getParsedBody();
$param_ = $param;
$resp->getBody()->write($param);
return $resp;
}
This is my Backend Code. When I try to read the parsedBody, its just empty.
If I send a request with PostMan its accept the data and I get the data in the $param variable.
Can someone find some errors? I can't find them.

Related

I'm trying to send a post request to a new route in flask/react.js, what am I doing wrong?

I am trying to send the contents of a flashcard to a backend route http://127.0.0.1:5000/post onClick and it works when I send the data to webhook.site but when I change it to http://127.0.0.1:5000/post I get the error " question = data['question' TypeError: 'NoneType' object is not subscriptable ". Here is the code for the fetch request: async function postData() {
try {
let result = await fetch('http://127.0.0.1:5000/post', {
method: 'POST',
mode: 'no-cors',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
key: `${Date.now()}`,
question: flashcard.question,
answer: flashcard.answer,
options: flashcard.options
})
});
} catch(e) {
console.log(e)
}
}
and here is the code for the backend route in flask:
#app.route('/post', methods=['GET', 'POST'])
def post():
data = request.get_json()
question = data['question']
answer = data['answer']
options = data['options']
key = data['key']
return jsonify({'question' : question, 'answer' : answer, 'options' : options, 'key' : key})
if __name__ == "__main__":
app.run(debug=True)
I get that the error is stating that "data" has no value which I assume means it's not recieving the JSON objects that I'm posting. It's weird because it works perfectly when I use a webhook.site url. can anyone help? thanks for your time!

Can't send image to server, getting "Error: Request failed with status code 500" while sending image file by axios in react native project

I am using react native RNCamera. I am getting the file uri from the data retuned by react native RNCamera
Here is the code how I did that
const mimeType = mime.getType(damageImage.uri);
console.log('received image', damageImage.uri, mimeType);
//Here I am getting damageImage.uri as file:///data/user/0/com.tvsmobile/cache/Camera/2c32593e-5015-4ef1-b8b0-db141628444e.jpg
// and mime type: image/jpeg
try {
const formData = new FormData();
formData.append('Content-Type', 'image/jpeg');
formData.append('damage_image', {
uri: Platform.OS === 'android' ? damageImage.uri : damageImage.uri.replace('file://', ''),
name: 'image.jpg',
type: mimeType, //I tried by passing 'image/jpeg' here
});
let response = await axios.request({
baseURL: base_url,
method: 'post',
url: headRoute + transactionRoute + damageRoute + 'add/',
headers: {
'accept': 'application/json',
'Content-Type': 'multipart/form-data',
},
data: JSON.stringify(formData),
});
return response.data;
} catch (e) {
console.log('error at sending damage asset:' + e);
const response = e.response;
switch (response.status) {
case 601:
case 605:
case 606:
Snackbar.show({text: response.data.errMessage});
break;
default:
Snackbar.show({text: defMsg});
break;
}
}
Any help will appreciate
Thanks in advance
Error 500 means an error has happened on the server side (https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500), so by inspecting front-end code is rather difficult, if not impossible, to say what is the cause. If you are able, you should check the server logs to find the cause, which might or might not be caused by your data.

403 when upload file to S3 bucket using axios

I'm using axios to upload an audio file to AWS s3 bucket.
The workflow is: React => AWS API Gateway => Lambda.
Here is the backend Lambda code where generates the S3 presigned URL:
PutObjectRequest putObjectRequest = PutObjectRequest.builder()
.bucket(AUDIO_S3_BUCKET)
.key(objectKey)
.contentType("audio/mpeg")
.build();
PutObjectPresignRequest putObjectPresignRequest = PutObjectPresignRequest.builder()
.signatureDuration(Duration.ofMinutes(10))
.putObjectRequest(putObjectRequest)
.build();
PresignedPutObjectRequest presignedPutObjectRequest = s3Presigner.presignPutObject(putObjectPresignRequest);
AwsProxyResponse awsProxyResponse = new AwsProxyResponse();
awsProxyResponse.setStatusCode(HttpStatus.SC_OK);
awsProxyResponse.setBody(
GetS3PresignedUrlResponse.builder()
.s3PresignedUrl(presignedPutObjectRequest.url().toString())
.build().toString());
return awsProxyResponse;
Here is the java code to create the bucket:
private void setBucketCorsSettings(#NonNull final String bucketName) {
s3Client.putBucketCors(PutBucketCorsRequest.builder()
.bucket(bucketName)
.corsConfiguration(CORSConfiguration.builder()
.corsRules(CORSRule.builder()
.allowedHeaders("*")
.allowedMethods("GET", "PUT", "POST")
.allowedOrigins("*") // TODO: Replace with domain name
.exposeHeaders("ETag")
.maxAgeSeconds(3600)
.build())
.build())
.build());
log.info("Set bucket CORS settings successfully for bucketName={}.", bucketName);
}
In my frontend, here is the part that try to upload file:
const uploadFile = (s3PresignedUrl: string, file: File) => {
let formData = new FormData();
formData.append("file", file);
formData.append('Content-Type', file.type);
const config = {
headers: {
"Content-Type": 'multipart/form-data; boundary=---daba-boundary---'
//"Content-Type": file.type,
},
onUploadProgress: (progressEvent: { loaded: any; total: any; }) => {
const { loaded, total } = progressEvent;
let percent = Math.floor((loaded * 100) / total);
if (percent < 100) {
setUploadPercentage(percent);
}
},
cancelToken: new axios.CancelToken(
cancel => (cancelFileUpload.current = cancel)
)
};
axios(
{
method: 'post',
url: s3PresignedUrl,
data: formData,
headers: {
"Content-Type": 'multipart/form-data; boundary=---daba-boundary---'
}
}
)
.then(res => {
console.log(res);
setUploadPercentage(100);
setTimeout(() => {
setUploadPercentage(0);
}, 1000);
})
.catch(err => {
console.log(err);
if (axios.isCancel(err)) {
alert(err.message);
}
setUploadPercentage(0);
});
};
However, when try to upload the file, it return 403 error.
And if I use fetch instead of axios instead and it works, like this:
export async function putToS3(presignedUrl: string, fileObject: any) {
const requestOptions = {
method: "PUT",
headers: {
"Content-Type": fileObject.type,
},
body: fileObject,
};
//console.log(presignedUrl);
const response = await fetch(presignedUrl, requestOptions);
//console.log(response);
return await response;
}
putToS3(getPresignedUrlResponse['s3PresignedUrl'], values.selectdFile).then(
(putToS3Response) => {
console.log(putToS3Response);
Toast("Success!!", "File has been uploaded.", "success");
}
);
It seems to me that the only difference between these two is that: when using fetch the request's Content-Type header is Content-Type: audio/mpeg, but when using axios it is Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryClLJS3r5Xetv3rN7 .
How can I make it work with axios? I'm switching to axios for its ability to monitor request progress as I want to show an upload progress bar.
I followed this blog and not sure what I missed: https://bobbyhadz.com/blog/aws-s3-presigned-url-react
You are using POST in your axios. Should be PUT instead.
Also I think the content type has to match the one specified during requesting the pre-signed URL, which is audio/mpeg as you rightly pointed out.
Correspondingly, your data should be just file, instead of formData.
axios(
{
method: 'put',
url: s3PresignedUrl,
data: file,
headers: {
"Content-Type": 'audio/mpeg'
}
}
...
You didn't mark any answers as accepted so I guess you didn't solve it.
For any future viewers out there. The reason why you are getting 403 forbidden error is because your Content-Type in your server and client side are not matching. I'm assuming you set up the AWS policies correctly.
Your code in the backend should look like this:
const presignedPUTURL = s3.getSignedUrl("putObject", {
Bucket: "bucket-name",
Key: String(Date.now()),
Expires: 100,
ContentType: "image/png", // important
});
and in the front-end (assuming you are using axios):
const file = e.target.files[0]
const result = await axios.put(url, file, {
withCredentials: true,
headers: { "Content-Type": "image/png" },
});
In practical, you would normally have to send the file type to generate the pre-signed url in the POST body or whatever and then in axios you do file.type to get the file type of the uploaded file.
Check your Lambda execution role. It may be the culprit. Perhaps it does not grant enough permissions to allow PUTting files into your bucket.
URL signing is a delegation of power on behalf of the signer, which is restricted to a specified object, action... Signing does not magically grants full read/write permissions on S3, even on the specific object related to the presigned URL.
The "user" who generates the signature requires sufficient permissions to allow the actions you want to delegate through that presigned URL. In this case, this is the execution role of your Lambda function.
You can add the AmazonS3FullAccess managed policy to the execution role and see if it solves your situation. This change took me out of a blocked situation me after days of struggle. Afterwards, before going to production, restrict that rule to the specific bucket you want to allow uploads into (least privilege principle).
If you develop using SAM local emulation, those execution roles seem not to be taken into account as long as you run your functions locally; the signed links work in that context even without S3 permissions.

Passing multiple object to axios post request but it's not working

I am trying to pass 3 objects the first is of type Text and the 2 others are of type MultipartFile to my back-end controller but it's not working, it's always empty field I don't know either syntax is wrong or how am passing the object it's not the correct way, I tried different ways but still not working
there is my front-end api call :
export const addNewText = (text, pdfFile, xlsFile) => (dispatch) => {
const data = {
text,pdfFile,xlsFile
}
axios({
method: 'POST',
url: 'http://localhost:8080/text/',
data: data,
headers: { "Content-Type": "multipart/form-data" }
});
}
this is my back-end controller function :
#PostMapping("/")
public String addText(#RequestBody Text text,#RequestParam("pdfFile") MultipartFile
pdfFile,#RequestParam("xlsFile") MultipartFile xlsFile) {
System.out.println("========>"+text.getTitre());
return "succes";
}
I was just testing to print the text title from the object that I passed through that post request but it's always null
Rest API should be updated as below
#PostMapping("/",consumes = {"multipart/form-data"})
public String addText(#RequestPart Text text,#RequestPart("pdfFile") MultipartFile
pdfFile,#RequestPart("xlsFile") MultipartFile xlsFile) {
System.out.println("========>"+text.getTitre());
return "succes";
}
And UI code should be updated as below
axios({
method: 'POST',
url: 'http://localhost:8080/text/',
data: data,
headers: {
"Content-Type": "multipart/form-data"
}
});

ReactJS image uploading is not working

I'm trying to upload an image using the code sample given in Codepen
I'm having the file contents in my state variable and getting it in the console from the below mentioned submit function
_handleSubmit(e) {
e.preventDefault();
console.log(this.state.file)
payLoad = {
image: this.state.file,
}
axios({
method: 'post',
url: this.state.url+'/task',
data: payLoad,
headers: {
'content-type': 'multipart/form-data'
}
})
}
My console result of this.state.file is
File(128544)
lastModified:1508143324556
lastModifiedDate:Mon Oct 16 2017 14:12:04 GMT+0530 (India Standard Time) {}
name:"sample.png"
size:128544
type:"image/png"
webkitRelativePath:""
__proto__:File
But the Network shows image variable as {} in API request headers and image is not uploading. Can anyone help? As i'm new to ReactJS I'm really trouble in some features and forced to ask many questions here.
You need to use FormData, because you are sending a file with content_type as content_type="multipart/form-data".
Try this:
_handleSubmit(e) {
e.preventDefault();
console.log(this.state.file)
let data = new FormData();
data.append('image', this.state.file);
axios({
method: 'post',
url: this.state.url+'/task',
data,
headers: {
'content-type': 'multipart/form-data'
}
})
}
To check the FormData values you can use either FormData.get(key) or iterate over FormData.values() method.
Check this snippet:
let data = new FormData();
data.append('a', 1);
data.append('b', 2);
data.append('c', 3);
data.append('d', 4);
// using formdata.get(key) method
console.log('a = ', data.get('a'));
// iterating over values
for(let el of data.values()){
console.log('el = ', el);
}

Resources