Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

vminds's avatar

Using ajax (with vanilla js) in laravel validation.

hi Dear, I want sending data to laravel validation (Form Request Validation) by pure vanilla JS Ajax (not by jQuery). with jQuery everything is ok and I get json response If validation fails with status code 422. But with vanilla js ajax (XMLHttpRequest) when there are any validation fails, the page redirect backs and so app could not send any json response and getting status code 302 and everything goes wrong.

sincerely yours.

let xhr = new XMLHttpRequest(); xhr.onload = function() {

  console.log(JSON.parse(xhr.responseText));

}

xhr.open("POST", "{{ route('login2') }}", true); xhr.send(frmData);

0 likes
10 replies
tykus's avatar
tykus
Best Answer
Level 104

Set the Accept header to application/json so you get JSON back

let xhr = new XMLHttpRequest(); 

xhr.onload = function() {
  console.log(JSON.parse(xhr.responseText));
}

xhr.open("POST", "{{ route('login2') }}", true); 

xhr.setRequestHeader('Accept', 'application/json');

xhr.send(frmData);
1 like
jlrdw's avatar

Another option is use fetch js.

1 like
tykus's avatar

@vminds whether you choose xmlHttpRequest or fetch; the header needs sending so Laravel response 422 and JSON rather than 302 and redirecting:

fetch({{route('login2')}}, {
  method: 'POST',
  body: frmData,
  headers: {
    Accept: 'application/json',
  }      
})
.then(res => res.json())
.then(json => console.log(json));
1 like
vminds's avatar

@tykus ... my issue was solved with your solution and other friends. It's great and thanks alot. According to your recommendation I tried "fetch Api" but could not get right result and I get status code 419 instead of 422. because of I'm sending CSRF code, It seems there are some problems about sending this code.

my front code is like below:

const fields = { user_index: document.getElementById('user-name').value.trim(), password: document.getElementById('password').value.trim(), _token: document.getElementsByName("_token")[0].value };

        fetch("{{ route('login2') }}", {
                method: 'POST',
                headers: {
                    Accept: 'application/json',
                },

                body: fields
                // body: JSON.stringify(fields)
            })
            .then(res => {
                if (!res.ok) {
                    throw new Error(`Response Status: ${res.status}`);
                }

                return res.json();
            })
            .then(data => {
                console.log(data);

            })
            .catch(error => {
                // Handle any errors that occurred during the fetch
                console.error('Fetch Catch Error:', error.message);
            });
tykus's avatar

@vminds is the CSRF token (_token) field amongst the form data; or a meta element on the page?

tykus's avatar

@vminds if you use the FormData API, then you should be able to get the all of the fields as JSON like this:

const form = document.getElementById('form'); // or however you get the Form
form.addEventListener('submit', (e) => {
  e.preventDefault();
  const formData = new FormData(form);
  const fields = Object.fromEntries(formData.entries());
  // send the request with Fetch
})

Given that the CSRF token is in the form, then it will also be in the JSON payload sent to the server

1 like
vminds's avatar

@tykus Thank you so much for your response. I tried and find that using formData directly as body of my fetch is correct and I'm fine now. According to fetch document we can use both "body: formData" and string type like "body: JSON.stringify({ username: "example" }) ". I don't know in my case why the second option doesn't work. Thank you very much for your time.

jlrdw's avatar

Also by far axios js is the easiest to use, but there were some security issues with axios, and I admit I don't fully understand the issues. I use fetch js for now.

1 like

Please or to participate in this conversation.