How to submit form via AJAX and validate CSRF?
- bernhard
- Member | 52
Hi,
I want to submit a nette form via AJAX and did not find any information on the internet how that can be done… This is what I have so far: Using isValid() works as long as I do not add a CSRF token to the form! This is how I'm checking the form:
This is how I send the ajax request (using the uikit js microframework):
Can anybody point me into the right direction please?
Thx in advance!
- Rick Strafy
- Nette Blogger | 81
Are you using forms only and not whole nette/application? o.O
Try to look at https://naja.js.org, if you use that, you can add ajax class
to your form and it will work.
Btw, use onSuccess callback if you can, for example https://github.com/…resenter.php#L62
(form is created in SnippetFormFactory)
Last edited by Rick Strafy (2021-06-11 16:43)
- bernhard
- Member | 52
Hi Rick,
thx for your answer! Yes, I forgot that to mention… I'm using Nette Forms standalone combined with the ProcessWire CMS. Thx also for pointing me to naja.js but that seems like overkill if all I want to do is submitting a form via ajax? Also I'm not a JS guru, so all those modern tools are a bit hard to understand – especially without having examples :(
What do you mean with “use onSuccess callback”? What would I use it for? How would that work? I don't understand the syntax $form->onSuccess[] = … :(
Is there a way to send form data via AJAX and validate on the backend? Why would I need an additional framework/library for that??
Sorry, I'm a little lost and would really appreciate some help!
- jiri.pudil
- Nette Blogger | 1032
Hi, the CsrfProtection
control intentionally
ignores the setValue()
method.
You should be able to:
- Submit the form using the standard
application/x-www-form-urlencoded
content type. The easiest way to achieve this is to pass theFormData
instance directly as the request's data. I don't know if UIkit supports this, but both XMLHttpRequest and Fetch API do, so I would be surprised if UIkit did not. - Then let nette/forms handle the data processing: just remove the
$form->setValues()
call and replace$form->isValid()
with$form->isSuccess()
– it checks if the form has been submitted and loads the data from the HTTP request automatically.
Last edited by jiri.pudil (2021-06-15 16:46)
- bernhard
- Member | 52
thx jiri.pudil!
The first part of your message worked :)
But unfortunately part 2 does not… checking $form->isSuccess() returns false all the time.
Checking the content of php://input shows this: https://i.imgur.com/L4INvbJ.png
So the data is there, but how can I bring that data into the form and check for successful submission?
This is what I'm using on JS – but I think the problem is on the server side…
Last edited by bernhard (2021-06-15 18:07)
- jiri.pudil
- Nette Blogger | 1032
Well, apparently the client-side solution sends the request as
multipart/form-data
. Try omitting the explicit
Content-Type
header, I believe the client should be able to
populate the header automatically based on what kind of data you pass
to it.
Server-side, nette/forms loads the values from $_POST
automatically. You don't need to (and really shouldn't) setValues()
from stdin. As long as PHP can correctly populate the $_POST
superglobal, it should all be working with just the isSuccess()
condition I've mentioned before.
- bernhard
- Member | 52
Hey Jiri :)
Thank you!! That was the problem!! Great. Now I have a super simple setup without any external dependencies and super simple form code on the PHP side :)))
For everybody else interested in this topic this is my working solution:
CLIENT
SERVER
As easy as that :)