POST convert to GET when I want to fetch formData? - javascript

I want to send an image to server
my code works perfect in Chrome Version 77.0.3865.90
BUT
in Mozilla Firefox (version 69.0.1) POST method changes to GET with this error
Form contains a file input, but is missing method=POST and enctype=multipart/form-data on the form. The file will not be sent.
Request URL: http://localhost:3000/...
Request method: GET
Status code: 200
<form class="form-horizontal" id="form" >
<div class="col">
<label for="images" class="control-label">image</label>
<input type="file" class="form-control" name="images" id="images" >
</div>
<div class="form-group row">
<div class="col">
<button type="submit" class="btn btn-danger">Send</button>
</div>
</div>
</form>
<script>
document.getElementById('form').addEventListener('submit' , async function(event) {
let images = document.querySelector('input[name="images"]');
let formData = new FormData();
formData.append('images' , images.files[0] );
try {
const response = await fetch('http://exampleurl.com/profile', {
method: 'POST',
headers: {
'X-Requested-With': 'XMLHttpRequest',
'X-CSRF-Token': "<%= req.csrfToken() %>",
},
body: formData,
credentials: 'same-origin'
});
} catch (error) {
console.error(error);
}
})
</script>
I can't use method ="POST" and enctype= "multipart/form-data" in the form because csrf tokens can't implement in forms with multipart/form-data enctype

I suspect your form might be submitting twice.
1) AJAX event handler
2) The submit button in the form actually posting the form through html
Try adding the event handler to the form itself, rather than the submit button.
There you can prevent the form from doing what it wants to do so only your AJAX request will go through.
https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/submit_event

Related

Second Post request puts form before URL for some reason

I'm creating a form using TailwindCSS and DaisyUI, which looks like this (removed the classes since they aren't relevant to this question):
<form id="form" >
<div>
<label for="name">Name</label>
<input id="name" type="text" name="name" required />
</div>
<div>
<label for="email">E-Mail</label>
<input id="email" type="email" name="email" required />
</div>
<div>
<label for="text">Info</label>
<textarea id="text" name="text" rows="5"></textarea>
</div>
<div>
<button id="submit-button" type="button">Request</button>
</div>
</form>
Since I plan to display some message after the request, I changed the button type to "button" and created this script using JQuery:
async function sendRequest(data) {
let response = await fetch('api/anfrage', {
method: 'POST',
headers: {
'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json',
"cache-control": "no-cache"
},
body: JSON.stringify(data)
})
let content = await response.json()
console.log(content)
return false
}
$(document).ready(() => {
$('#submit-button').click(() => {
let data = {
name: $('#name').val(),
email: $('#email').val(),
text: $('#text').val()
}
console.log(data)
sendRequest(data)
})
})
My backend is a Flask server, which has this endpoint:
#index_bp.route("/api/anfrage", methods=["POST"])
def request_meeting():
print("request_meeting")
return {"yes": "yesss"}
Everything works exactly as you would suspect on the first run. However, when I submit the same form again, I'm getting this error from my Flask server:
"{"name":"dasdf","email":"galstyan.artu#gmail.com","text":"asdf"}POST /api/anfrage HTTP/1.1" 405 -
For some reason, the content of my form is placed before the POST request. It's incredibly confusing and I've never had this before. If I don't send a second request and instead refresh the page, I'm getting this error:
127.0.0.1 - - [04/Sep/2022 13:12:31] "{"name":"dasdf","email":"galstyan.artu#gmail.com","text":"asdf"}GET / HTTP/1.1" 405 -
Does anyone have an idea? Thanks :)

How do I do this with javascript fetch

I was checking out this answer.
It's basically a request to Mailchimp to send a confirmation email to the user when they submit their email.
The code works perfectly with jquery. But I don't like jquery. And it's kind of annoying to have to add it just for this tiny snippet, since I won't be using it in the rest of my project. I already tried "translating" this into vanilla javascript using fetch but it doesn't seem to work.
function register($form) {
$.ajax({
type: $form.attr('method'),
url: $form.attr('action'),
data: $form.serialize(),
cache : false,
dataType : 'json',
contentType: "application/json; charset=utf-8",
error : function(err) { alert("Could not connect to the registration server. Please try again later."); },
success : function(data) {
if (data.result != "success") {
// Something went wrong, do something to notify the user. maybe alert(data.msg);
} else {
// It worked, carry on...
}
}
});
}
EDIT
Some suggested I should add the HTML form:
I am doing all this because I want to send the user email to my MailChimp subscription list. But I want it to do it directly from my website without redirecting to the Mailchimp subscription page.
<form action="https://herokuapp.us5.list-manage.com/subscribe/post-json?u=070e69e5e3e6e664a8066e48f&id=0bf75ac6c4&c=?" method="get" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate newsletter__form" target="_blank">
<label for="mce-EMAIL">Ingresa tu correo electrónico:</label>
<input type="email" placeholder="ejemplo#gmail.com" value="" name="EMAIL" class="required textfield email__textfield" id="mce-EMAIL">
<input type="submit" value="suscribirme" name="subscribe" id="mc-embedded-subscribe" class="button raise">
<div id="mce-responses" class="clear">
<div class="response" id="mce-error-response" style="display:none"></div>
<div class="response" id="mce-success-response" style="display:none"></div>
</div> <!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups-->
<div style="position: absolute; left: -5000px;" aria-hidden="true"><input type="text" name="b_070e69e5e3e6e664a8066e48f_0bf75ac6c4" tabindex="-1" value=""></div>
</form>
I also found out jquery ajax method get accepts the data argument but it takes what's inside of the data and adds it to the URL. So it's still a get request with no body. I am trying to find a way to do that but with fetch but somehow the jquery URL has things I don't know where they come from. I also tried doing this with POST method and fetch but apparently, the server doesn't allow that.
For what is worth this is how the URL generated by jquery request looks like:
https://herokuapp.us5.list-manage.com/subscribe/post-json?u=070e69e5e3e6e664a8066e48f&id=0bf75ac6c4&c=jQuery35105022544193369527_1633147928440&EMAIL=email123456%40gmail.com&b_070e69e5e3e6e664a8066e48f_0bf75ac6c4=&_=1633147928441
And this is how I can trick my URL to look like with fetch. Here I get a CORS error
https://herokuapp.us5.list-manage.com/subscribe/post-json?u=070e69e5e3e6e664a8066e48f&id=0bf75ac6c4&c=?&EMAIL=paula.uzcategui68%40gmail.com&b_070e69e5e3e6e664a8066e48f_0bf75ac6c4=
And this is what I'm doing with fetch
function register(form) {
data = new FormData(form);
data = Object.fromEntries(data);
data = Object.entries(data);
let arroba = /#/gi;
let action = form.getAttribute("action")+ "&"+ data[0][0] +"="+ data[0][1].replace(arroba, '%40') + "&" + data[1][0] + "=" + data[1][1]
// console.log(action)
fetch(action, {
method: 'get',
cache: 'no-cache',
headers: {
'content-type': 'application/json; charset=utf-8'
},
})
.then(response => response.json())
.catch(error => {
alert("Could not connect to the registration server. Please try again later."+ error)
});
}
Try this, it is the exact solution for your question (I hope). If you still get stuck please comment down, I will explain.
async function register(form) {
let data = new FormData(form);
data = JSON.stringify(Object.fromEntries(data)); // convert formdata to json
let response = await fetch(form.action, {
method: form.method,
body: data,
cache: 'no-cache',
headers: {
'content-type': 'application/json; charset=utf-8'
}
})
.then(response => response.json())
.catch(error => {
alert("Could not connect to the registration server. Please try again later.")
});
}

Improperly sending form data in html

So i would like to send Whatever i type in my input bar in to be sent to whatever api link via post method. But whenever i send it i get {} . The problem is when i dont send anything in the input bar A.K.A left blank and press submit i still get {}. But when i type gibberish its still {} . So i assume whatever i typed in is not being sent to the api link.
Also when i hard code something like body: JSON.stringify(this.myForm) it shows up as a response in the back end. So i believe i error lies withing this body of my fetch request. heres my code what should i put for the body.
<html>
<body>
<h1>Draft V0.1</h1>
<form class="form" id="myForm">
<label for="skill">add skill</label>
<input type="text" name="skill" id="skill">
<button type="submit">Submit</button>
</form>
<script>
const myForm = document.getElementById('myForm')
myForm.addEventListener('submit', function (e) {
e.preventDefault();
const formData = new FormData(this);
fetch('https://fj5s3i60a8.execute-api.us-east-1.amazonaws.com/updateSkill', {
method: 'post',
body: JSON.stringify(new FormData(myForm)),
headers:
{
"Content-Type": "application/json; charset=utf-8",
"Accept": 'application/json'
}
}).then(function (response) {
console.log(response)
return response.json();
});
});
</script>
</body>
</html>
Note I was blindly playing around with the body to see what i can parse through it but i would end up getting cors errors.
Thank you in advance
const thisForm = document.getElementById('myForm');
thisForm.addEventListener('submit', async function (e) {
e.preventDefault();
const formData = new FormData(thisForm).entries()
const response = await fetch('https://reqres.in/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(Object.fromEntries(formData))
});
const result = await response.json();
console.log(result)
});
<html>
<body>
<h1>Draft V0.1</h1>
<form class="form" id="myForm">
<label for="skill">add skill</label>
<input type="text" name="skill" id="skill">
<button type="submit">Submit</button>
</form>
</body>
</html>

How do I console.log my POST. When i try to GET all i get in console is "null"

So here is my code. My POST function seems to work. But when I try to console.log my POST from the server all I get is "null".
What I need help with is to properly POST to my form to the server. And then be able to retrieve it and post it to to my console.
I then have to post it to my website, but that i can manage for myself.
const myForm = document.getElementById("myForm");
myForm.addEventListener("submit", function(e) {
e.preventDefault();
const formData = new FormData(this);
formData.append("store", "vetlekw1");
fetch("http://folk.ntnu.no/oeivindk/imt1441/storage/add.php?", {
method: "post",
body: formData
})
.then(function(response) {
return response.text();
})
.then(function(text) {
console.log(text);
});
});
document.querySelector(".hent").addEventListener('click', e=>{
fetch('http://folk.ntnu.no/oeivindk/imt1441/storage/getAll.php?store=vetlekw1')
.then(res=>res.json())
.then(data=>{
console.log(data);
})
})
<section id="addContact">
<h1>add Contact</h1>
<form class="form" id="myForm" >
<label for="fornavn">Name</label>
<input type="text" id="fornavn"><br>
<label for="etternavn">Surname</label>
<input type="text" id="etternavn"><br/>
<label for="tlf">Tlf</label>
<input type="text" id="tlf"><br>
<button type="submit">add</button>
</form>
</section>
<br>
<button class="hent">Get</button>
You don't give back the expected data from your server endpoint. Maybe your db query gives no result or you are using a wrong variable or something else.

upload image with reactjs and ajax

I'm trying to upload an image through a form to a url/api.
I call handleImgUpload() method on submitting the form.
The problem is that the request sent is empty.
I think that new FormData(this) does not work with react or something.
There's another function that sets the image path.
handleImgUpload(e){
e.preventDefault();
$.ajax({
url: "my url goes here", // Url to which the request is send
type: "POST", // Type of request to be send, called as method
data: new FormData(this), // Data sent to server, a set of key/value pairs (i.e. form fields and values)
contentType: false, // The content type used when sending data to the server.
cache: false, // To unable request pages to be cached
processData:false, // To send DOMDocument or non processed data file it is set to false
success: function(data){ // A function to be called if request succeeds
console.log(new FormData(this));
}
});
}
here is the form:
<form id="uploadimage" onSubmit={this.handleImgUpload} action="" method="post" encType="multipart/form-data">
<Row id="image_preview" className="row">
<img id="previewing" src={this.state.imgPath}/>
</Row>
<div id="selectImage">
<label>Select Your Image</label><br/>
<input type="file" name="image" id="file" onChange={this.handleImgChange} required />
<Button type="submit" className="btn btn-primary" id="upload">Upload</Button>
</div>
</form>
this is going to be the React component, not the form, which can be found in event.target
handleImgUpload(e) {
e.preventDefault()
let formData = new FormData(e.target)
for (let [key, val] of d.entries()) {
console.log(key, val) <-- should log the correct form data
}
// ajax stuff
}

Categories

Resources