Regenerate CSRF Token If ajax request has an error - javascript

I'm using ajax request to submit registration form. If a user submit form on first attempt with correct information, the request is working well. But If user made any mistake, correct the information and submit again, the data is inserted but in console.log(data), I'm facing this error:
"CSRF token mismatch."
"\vendor\laravel\framework\src\Illuminate\Foundation\Exceptions\Handler.php".
Line: 389.
head.blade.php
<meta name="csrf-token" content="{{ csrf_token() }}">
My Blade view:
$(document).ready(function() {
$('#send_form').click(function(e) {
e.preventDefault();
/*Ajax Request Header setup*/
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$('#send_form').html('Sending..');
/* Submit form data using ajax*/
$.ajax({
url: "{{ route('register')}}",
method: 'POST',
data: $('#ajax-register-form').serialize(),
success: function(response) {
$('#send_form').html('Submit');
document.getElementById("ajax-register-form").reset();
},
error: function(data) {
var errors = data.responseJSON;
console.log(errors);
$('.error-warning').show();
}
});
});
});
If user has an error on first attempt, the csrf token should regenerate so user can submit the form without refreshing the whole page.

Remove headers from $.ajaxSetup and put it in send_form request like this.
$('#send_form').html('Sending..');
/* Submit form data using ajax*/
$.ajax({
url: "{{ route('register')}}",
method: 'POST',
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
data: $('#ajax-register-form').serialize(),
success: function(response) {
$('#send_form').html('Submit');
document.getElementById("ajax-register-form").reset();
},
error: function(data) {
var errors = data.responseJSON;
console.log(errors);
$('.error-warning').show();
}
});
});

Related

Ajax post requests 403 error only for some users?

I've been testing my site by having friends try it, and some friends get the 403 Forbidden error on any function using ajax. I'm confused why only some of them get the error, especially when everyone used the same browser. Does anyone know why? I'm using Django as a framework and I think I've done everything in the documentation here
Example of one of my functions using ajax:
$('#button').click(function(){
$.ajax({
url: '/get_url/',
type: "POST",
data: {
data_name: data_to_send
},
beforeSend: function (xhr) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
},
success: function (data) {
//change some html text using data
},
error: function (error) {
console.log(error);
}
});
});
use this:
$('#button').click(function(){
$.ajax({
url: '/get_url/',
type: "POST",
data: {
data_name: data_to_send
},
headers: {
"X-CSRFToken": "{{ csrf_token }}",
},
success: function (data) {
//change some html text using data
},
error: function (error) {
console.log(error);
}
});
});
Fixed by making sure all of my form tags had method='post' and {{ crsf_token }}.

Ajax works periodically. Sometimes POST request return error 419

With the help of Laravel I create a multilingual website. When I switch languages using Ajax, sometimes I get an error.
Javascript code:
$(document).ready(function(){
$("#LanguageSwitcher").change(function(){
var locale = $(this).val();
var _token = $('meta[name="csrf-token"]').attr('content');
$.ajax({
url: "/language",
type: 'POST',
data: {locale: locale, _token: _token},
datatype: 'json',
beforeSend: function () {
console.log('before send - ' + locale);
},
success: function (data) {
console.log('success');
},
error: function (error) {
console.log(error);
},
complete: function (data) {
window.location.reload(true);
}
});
});
});
web.php:
Route::post('/language/', array(
'before' => 'csrf',
'uses' => 'LanguageController#changeLanguage'
));
Controller:
class LanguageController extends Controller
{
public function changeLanguage(Request $request){
if ($request->ajax()) {
$request->session()->put('locale', $request->locale);
}
}
}
layout.blade.php:
<meta name="csrf-token" content="{{ csrf_token() }}">
<select id="LanguageSwitcher" class="btn btn-outline-danger">
<option>...code...</option>
<option>...code...</option>
<option>...code...</option>
</select>
When I go through another browser everything works. It also works if I go through the incognito mode. Can this be due to the fact that I log in to the admin panel?
Put your ajax call like this.
req = $.ajax({
type: "POST",
url: "/search",
data: {
"locale": locale,
"_token": "{{ csrf_token() }}",
},
dataType: "json",
success: function(msg){
}
});
As I saw your code.
You passing csrf token in your request. the problem you face is, your csrf token is not being updated.
Let's say, you're not reloading your page, on first time your enter to your page, laravel give you csrf token which you providing to ajax through meta.
But after some time on the backend(laravel side). your csrf token is updated, but you don't have updated one in client-side.For get the updating one you need to reload the page.
so for this issue, you need to check whenever you get error status 419, request laravel for new csrf token(by making a new route get the csrf token from laravel helper csrf_token() return back to ajax) and update to your file. and send back that token to laravel with you request.
For updating newly token to your page
document.querySelector('meta[name=csrf-token]').setAttribute('content', res.data.csrf);
or you can refresh your token by reloading the page
add csrf token in meta tag in your blade view
<meta name="csrf-token" content="{{ csrf_token() }}"/>
in your ajax function :
$.ajax({
url: '/search',
headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')},
type: 'POST',
dataType: 'json',
success: function(response) {
},error:function(err){
}
});
I found the answer, but still did not understand how it works, explain who understands this.
App\Exceptions\Handler.php
public function render($request, Exception $exception)
{
// code for updating token when session is expired
if ($exception instanceof \Illuminate\Session\TokenMismatchException) {
return Redirect::back()->withErrors(['session' => 'Sorry, your session seems to have expired. Try Again']);
}
return parent::render($request, $exception);
}

Is it possible to insert data with ajax request by only using the csrf field instead of token?

I'm trying to insert data with CSRF field. I really don't have the idea of CSRF token. (new to laravel). I'm getting unknown status error in /classwork/insert.
//This is my ajax function: I really can't understand what is wrong with the code.
Is it possible to do ajax calls with only using {{csrf-field}}
function insertData(e){
e.preventDefault();
var data = $(this).serialize();
$.ajax({
url: '/classwork/insert',
method: 'post',
data : 'data',
success:function(data){
console.log(data);
}
});
}
//This is my controller and Route:
public function insertTask(Request $request){
$task = new Task;
$task->task = $request->task;
$task->save();
}
//this is my route
Route::post('/classwork/insert', 'TaskController#insertTask');
Make a genric ajaxRequest function. Add this to meta
<meta name="csrf-token" content="{{ csrf_token() }}">
Then in your global ajax function do this;
public function ajaxRequest(options){
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
url: option.url,
method: option.method,
data : option.data,
success:function(data){
console.log(data);
}
});
}
Try using this way
Add this before ajax calling
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
Please always add this meta tag in main blade page
<meta name="csrf-token" content="{{ csrf_token() }}">
And instead of old scholl jquery ajax.. just use Axios. simple and very easy. it already detect the csrd-token meta tag. so no need to do in the form or header
change this
$.ajax({
url: '/classwork/insert',
method: 'post',
data : 'data',
success:function(data){
console.log(data);
}
});
to this
axios.post('/classwork/insert', data)
.then(function(response) {
console.log(response);
});

AJAX Post request not working with Laravel

I can do this:
$.ajax({
type: "GET",
async: true,
url: '/someurl/',
dataType: 'json',
success: function (data) {
console.log(data);
}
});
Web:
Route::get('/someurl','MyController#myfunction');
And it works just fine, but when I try the same with post:
$.ajax({
type: "POST",
async: true,
url: '/someurl/',
dataType: 'json',
success: function (data) {
console.log(data);
}
});
Route::post('/someurl','MyController#myfunction');
I get a 405 method not allowed error message in the console
POST using normal ajax need CSRF Token to be pass in POST Method
in your ajax
$.ajax({
type: "POST",
async: true,
url: '/someurl/',
dataType: 'json',
data : {"_token":"{{ csrf_token() }}"} //pass the CSRF_TOKEN()
success: function (data) {
console.log(data);
}
});
or
set head meta tag
<meta name="csrf_token" content="{{ csrf_token() }}" />
set header ajax
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
Add another route with
Route::post('/someurl','MyController#myfunction');
By the way u are not sending any data, in post we need to send data right..
Also check whether csrf token is being passed in data, if not as mentioned above try adding it manually.
If you are using {{Form...}} it would be automatically added to form data.

AJAX form sends GET & sends form to current page instead of POST jquery

I'm trying to submit a google doc form through AJAX, but it's not working. It keeps trying to send the form to the page I am on as a GET, rather than the google form POST url request I am trying.
My form looks like
<form id="ss-form" target="_self" onsubmit="" action="">
.....
<input type="submit" name="submit" value="Submit" id="ss-submit" class="jfk-button jfk-button-action ">
</form>
and my JS looks like:
<script>
$('#ss-form').submit(function(e) {
e.preventDefault();
$.ajax({
url: "https://docs.google.com/a/example.com/forms/d/e/1FAI324B_-XUt0dQ-0AmlfwdfUu5dbEefwjVNud_hNlOKQ/formResponse",
data: $(this).serialize(),
type: "POST",
dataType: "xml",
success: function(data) {
console.log('Submission successful');
},
error: function(xhr, status, error) {
console.log('Submission failed: ' + error);
}
});
});
</script>
But this just reloads my page like example.com?entry.1850833=test and it's as a GET request.
Any ideas why this is happening? How do I get it to send it through the AJAX code, and stop the form just refreshing on the current page as a GET?
try add return false
$.ajax({
url: "https://docs.google.com/a/example.com/forms/d/e/1FAI324B_-XUt0dQ-0AmlfwdfUu5dbEefwjVNud_hNlOKQ/formResponse",
data: $(this).serialize(),
type: "POST",
dataType: "xml",
success: function(data) {
console.log('Submission successful');
},
error: function(xhr, status, error) {
console.log('Submission failed: ' + error);
}
});
return false;
Remove "_self", there should be no target since you're submitting the form through AJAX.

Categories