I have a basic Netlify form (based on this guide) with name
, email
and message
fields. With the following submit function:
const handleSubmit = event => {
event.preventDefault();
const data = {};
const scopedForm = [...formState];
let isValidForm = validateForm(scopedForm);
setFormState([...scopedForm]);
if (!isValidForm) return false;
formInputs.forEach(input => data[input.name] = input.value);
fetch(`/`, {
method: `POST`,
headers: {
'Accept': `application/x-www-form-urlencoded;charset=UTF-8`,
'Content-Type': `application/x-www-form-urlencoded`,
},
body: encode({
'form-name': `Contact Form`,
...data,
}),
})
.then(() => console.log(`OK`))
.catch(error => alert(error));
};
const encode = data => {
return Object.keys(data)
.map(key => encodeURIComponent(key) + `=` + encodeURIComponent(data[key]))
.join(`&`);
};
Pretty simple, besides the validations, I create a data
object and I fill it with a pair of data[input.name] = input.value
. Everything works as expected locally, as well as in develop
and build
mode. I can see a POST
request, however, in production, it turns into a GET
:
I've tried changing the built-in fetch
to axios
but the result is the same. I don't know if I need to add some custom configuration in my server or how to bypass this.
My resulting HTML structure is:
<form name="Contact Form" method="POST" action="/" data-netlify="true" data-netlify-honeypot="bot-field" data-netlify-recaptcha="true">
<div><label for="form-name"><input type="hidden" name="form-name" value="Contact Form"></label></div>
<div><label for="bot-field"><input type="hidden" name="bot-field" value=""></label></div>
<div><label for="name">Name:<input type="text" name="name" value="Chancellor Lawson"></label></div>
<div><label for="email">Email:<input type="text" name="email" value="fivyhohy@mailinator.com"></label></div>
<div><label for="message">Message:<textarea name="message">Ea quisquam ea vel e</textarea></label></div>
<button type="submit">Send</button>
</form>
I have read a lot of similar issues, articles, and guides but none helped.
In order to close the issue, I will answer my own question, giving all the merits to Quentin. As he pointed out, the solution was removing the Accept
header since it only was accepting application/x-www-form-urlencoded;charset=UTF-8
requests. So the header should look like:
headers: {
'Content-Type': `application/x-www-form-urlencoded`,
},
From MDN documentation:
The Accept request
HTTP
header advertises which content types, expressed as MIME types, the client is able to understand. Using content negotiation, the server then selects one of the proposals, uses it and informs the client of its choice with theContent-Type
response header. Browsers set adequate values for this header depending on the context where the request is done: when fetching a CSS stylesheet a different value is set for the request than when fetching an image, video, or script.