PHP Laravel : TokenMismatchException in VerifyCsrfToken.php line 67 - php

Here the scenario is, I want to fetch some data from database and show it to user. While someone give some input and save it to database and I put a status with that which is always "0" until someone see it. So whenever a input has submitted user will see a pop up screen with that new data has inserted in another page. Here the problem is when ajax got some value with status "0" it shown it to screen but when it couldn't fetch any value ( when all the status value is 1)it shows error in console :
TokenMismatchException in VerifyCsrfToken.php line 67
.
How do I solve the issue , any possible suggestion please ?
Here is the route:
Route::post('/unread',[
'uses'=>'ItemController#getUnread',
'as'=>'unread'
]);
Route::post('/s_update',[
'uses'=>'ItemController#status_update',
'as'=>'s_update'
]);
Here is the controller :
public function getUnread()
{
$items=DB::select(DB::raw("SELECT count(*) as total from items where status =0"));
// $data=mysql_fetch_assoc($items);
return Response::json($items);
}
public function status_update()
{
$items=DB::select(DB::raw("UPDATE items SET status=1 WHERE status=0"));
return Response::json($items);
}
and here is the ajax call :
<script type="text/javascript">
setInterval(function(){
$(".container").load("list", function(){
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
type : "POST",
url : "{{url('unread')}}",
dataType : 'json',
success : function(data) {
$.each(data,function(index,subcatObj){
if(subcatObj.total != '0')
{
var yes = confirm('You have '+subcatObj.total+' new messages');
if(yes){
status_update();
}
}
});
},
});
});
}, 3000);
function status_update(){
$.ajax({
url:"{{url('s_update')}}",
method:"POST",
});
}
</script>

Change this route
Route::post('/unread',[
'uses'=>'ItemController#getUnread',
'as'=>'unread'
]);
to
Route::get('/unread',[
'uses'=>'ItemController#getUnread',
'as'=>'unread'
]);

I think this is because you are not sending the laravel csrf token in the post.
You need to send a field called "_token" in the json which is the csrf_token provided.
See here : https://laravel.com/docs/5.3/csrf

{{ csrf_field() }}
use this to generae csrf token in your form

Related

Laravel undefined variable into blade after calling from JSON

I've Signup form in my website. It was properly submitting before. Now I wanted to submit my form using ajax and wanted to return a variable from controller into JSON that I will use into blade file.
The form is submitting and values are showing into database but after redirection, it returns error.
Undefined variable: seller in report blade
I tried to decode my variable to make it work but still the same error.
How would I make it work?
Report-Blade
#foreach(json_decode($seller, true) as $row)
<a href="{{route('Report', $row->id) }}" >
{{ __('Show Report of ')}} {{$row->car_title}}
</a>
#endforeach
Controller
$seller = Sellers::take(1)->latest()->get();
return response(view('report',array('seller'=>$seller)),200, ['Content-Type' =>
'application/json']);
JavaScript
$("#submit-all").click(function(e){
e.preventDefault();
var _token = $('input[name="_token"]').val();
$.ajax({
type: "post",
url: "{{ route('form_for_private_sellers') }}",
data : $('#msform').serialize() + "&_token=" + _token,
dataType: 'JSON',
beforeSend: function(){
// Show loading image
$("#se-pre-con").show();
},
success: function(data) {
window.location = "http://127.0.0.1:8000/report/";
},
complete:function(data){
// Hide loading image
$("#se-pre-con").hide();
}
});
});
As understood from your comments,
window.location = "http://127.0.0.1:8000/report/";
will hit the route
Route::get('/report', function () {
return view('report');
})->name('private_seller_report');
Report blade expects a variable named $seller, and it is not being sent from the route. You would need to change the route to something similar to this:
Route::get('/report', function () {
$sellers = Seller::get(); //your logic
return view('report', ['seller' => $sellers]);
})->name('private_seller_report');
Alternatively you can point the route to a method in a controller if you want to avoid bulking up your routes.
you need two route for this
first for rendering blade
return view('report');
and the second for fetch seller
$seller = Sellers::latest()->take(1)->get();
return $seller

Save to database in yii2

I am trying to save to a database in yii2 using ajax but I am getting errors. I just want to insert the value or rate which is "up" into the database and I don't want to use a form, just on-click of a button.
This is my controller
public function actionThumbs()
{
$thumbs = new Thumbs;
$thumbs->user = Yii::$app->user->identity->email;
$thumbs->topic_id = Yii::$app->getRequest()->getQueryParam('id');
$thumbs->rate = $_POST["rate"];
if ($thumbs->load(Yii::$app->request->post()) ) {
$thumbs->load($_POST);
$thumbs->save();
return $this->redirect(['blog', 'id' => Yii::$app->getRequest()->getQueryParam('id')]);
}
return $this->redirect(['blog','id' => Yii::$app->getRequest()->getQueryParam('id')]);
}
This is my this is my ajax file
$("#mys").click(function() {
var rate = "up";
$.ajax({
type: 'POST',
url: 'vot/frontend/web/index.php?r=site%2Fthumbs',
data: 'rate='+rate,
success: function (rate) {
alert("test");
},
error: function (exception) {
alert(exception);
}
});
});
the view
<div>
<?= Html::Button('ups', ['class' => 'btn btn-primary', 'name' => 'mys' ,'id'=>'mys']) ?>
</div>
I get this alert error
The page at localhost says":
"[object Object]"
By default Yii2 controller doesn't accept POST request without _csrf protection, so there are 2 ways here:
1 - disable csrf:
public function actionThumbs() {
$this->enableCsrfValidation = false;
//your code here
}
2 - Send post request via ajax with _csrf token:
In your layout/main.php file, put this: <?= Html::csrfMetaTags() ?>
Before your "ajax" code, call this:
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content')
}
});
//Your ajax code here

Laravel 5: Redirecting to external link on POST request

The function below is called through a POST request. I need to retrieve URL from my database and open the link in a new tab. I'm using the Redirect::away() function for this. But it gives a MethodNotAllowedHttpException. I have tried calling this function in a GET request and it works perfectly fine.
public function generateURL(Request $request) {
$screenRow = \App\ScreenshotRow::find($request->input('row_ID'));
$baseURL = $screenRow->BaseURL;
$screenshot = \App\Screenshot::where('Setname', '=', $screenRow->Setname)->get();
$pageURL = $screenshot[0]['PageURL'];
if ($baseURL == "") {
return Redirect::away($PageURL);
}
else
return Redirect::away($baseURL);
}
Is there any way to calling this function in response to a POST request?
I would simply use an Ajax Form and redirect the User with Javascript.
Make sure to give your Form an ID
<form id="myForm" method="POST" action="{{ route('your.route') }}">
...
...
<button type="submit">Submit the Form</button>
And make this Form working with Ajax
<script>
$('#myForm [type="submit]').click(function(e){
e.preventDefault();
var form = jQuery(this).parents("form:first");
var dataString = form.serialize();
var formAction = form.attr('action');
$.ajax({
type: "POST",
url : formAction,
data : dataString,
success : function(data){
var url = $.parseJSON(data.responseText);
console.log(data);
// Redirect to a new tab with the given url
window.open(url.success, '_blank');
},
error : function(data){
var error = $.parseJSON(data.responseText);
console.log(error);
// Do what ever you want with an Error Message
alert(error)
}
},"json");
});
</script>
Okay - So if the Form receives a success Message, the success function is executed, otherwise the error function.
Lets go to the Backend Controller which handles the Request
public function generateURL(Request $request) {
$screenRow = \App\ScreenshotRow::find($request->input('row_ID'));
$baseURL = $screenRow->BaseURL;
$screenshot = \App\Screenshot::where('Setname', '=', $screenRow->Setname)->get();
$pageURL = $screenshot[0]['PageURL'];
// Return a JSON Success Message with a Success HTTP Status Code
if ($baseURL == "") {
return response()->json(['success' => $PageURL], 200);
}
// Return a JSON Error Message with a Error HTTP Status Code
else
return response()->json(['error' => $baseURL], 400);
}
Now if your Backend throws a Success Message the success function of the Ajax Form is called which redirects to a new tab based on the given url which you passed in your Backend Controller Success Response.
NOTE
To avoid the tokenmismatchexception on an Ajax Request, you should add the csrf_token to your meta Section in your <head>.
<meta name="csrf-token" content="{{ csrf_token() }}">
And fetch this csrf_token on every Form Request
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});

laravel 5 simple ajax retrieve record from database

How can I retrieve data using ajax? I have my ajax code that I've been using in some of my projects when retrieving records from database but dont know how to make it in laravel 5 because it has route and controller.
I have this html
<select name="test" id="branchname">
<option value="" disabled selected>Select first branch</option>
<option value="1">branch1</option>
<option value="2">branch2</option>
<option value="3">branch3</option>
</select>
<select id="employees">
<!-- where the return data will be put it -->
</select>
and the ajax
$("#branchname").change(function(){
$.ajax({
url: "employees",
type: "post",
data: { id : $(this).val() },
success: function(data){
$("#employees").html(data);
}
});
});
and in my controller, I declared 2 eloquent models, model 1 is for branchname table and model 2 is for employees table
use App\branchname;
use App\employees;
so I could retrieve the data like (refer below)
public function getemployee($branch_no){
$employees = employees::where("branch_no", '=', $branch_no)->all();
return $employees;
}
how to return the records that I pulled from the employees table? wiring from routes where the ajax first communicate to controller and return response to the ajax post request?
any help, suggestions, recommendations, ideas, clues will be greatly appreciated. Thank you!
PS: im a newbie in Laravel 5.
At first, add following entry in your <head> section of your Master Layout:
<meta name="csrf-token" content="{{ csrf_token() }}" />
This will add the _token in your view so you can use it for post and suchlike requests and then also add following code for global ajax setting in a common JavaScript file which is loaded on every request:
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
So, you don't need to worry or add the csrf_token by yourself for methods who require this _token. Now, for a post request you may just use usual way to make an Ajax request to your Controller using jQuery, for example:
var data = { id : $(this).val() };
$.post(url, data, function(response){ // Shortcut for $.ajax({type: "post"})
// ...
});
Here, url should match the url of your route declaration for the employees, for example, if you have declared a route like this:
Route::post('employees/{branch_no}', 'EmployeeController#getemployee');
Then, employees is the url and return json response to populate the select element from your Controller, so the required code for this (including javaScript) is given below:
$.post('/employees/'+$(this).val(), function(response){
if(response.success)
{
var branchName = $('#branchname').empty();
$.each(response.employees, function(i, employee){
$('<option/>', {
value:employee.id,
text:employee.title
}).appendTo(branchName);
})
}
}, 'json');
From the Controller you should send json_encoded data, for example:
public function getemployee($branch_no){
$employees = employees::where("branch_no", $branch_no)->lists('title', 'id');
return response()->json(['success' => true, 'employees' => $employees]);
}
Hope you got the idea.
First check url of page from which ajax call initiates
example.com/page-using ajax
In AJAX
If you call $.get('datalists', sendinput, function())
You are actually making GET request to
example.com/page-using ajax/datalists
In Routes
Route::get('page-using-ajax/datalists', xyzController#abc)
In Controller Method
if (Request::ajax())
{
$text = \Request::input('textkey');
$users = DB::table('datalists')->where('city', 'like', $text.'%')->take(10)->get();
$users = json_encode($users);
return $users;
}
In Ajax Success Function
function(data) {
data = JSON.parse(data);
var html = "";
for (var i = 0; i < data.length; i++) {
html = html + "<option value='" + data[i].city + "'>";
};
$("#datalist-result").html(html);
}
Add in your route:
Route::post('employees', [
'as' => 'employees', 'uses' => 'YourController#YourMethod'
]);
Ajax:
Change:
url: "employees"
to:
url: "/employees"

Form submission using ajax and page view moderation after the submission

At this moment I am using laravel. In this context I am having a form which is successfully submitted by using ajax to a controller. and that controller make it to the database. But the problem is as the ajax is doing its job the whole page remain unmoved / unchanged after the submission even the database is updated.
Now what I want
I want to give feedback to the user that your post is successfully submitted there. or what I want to do in further, I want to refresh the section in which the post is collected from the database as this post can be retrieved from there. But by using ajax only.
So there is no need to collect the whole page or refresh.
here is my form structure
`
{{ Form::open(array('route' => array('questions.store'), 'class' => 'form-horizontal' )) }}
blah blah blaaa .......
<script type="text/javascript">
$(".form-horizontal").submit(function(e){
$(this).unbind("submit")
$("#ask").attr("disabled", "disabled")
var that = $(this),
url = that.attr('action'),
type = that.attr('method'),
data = {};
that.find('[name]').each(function(index, value){
var that = $(this),
name = that.attr('name'),
value = that.val();
data[name] = value;
});
$.ajax({
url: url,
type: type,
data: data,
success: function(response){
console.log(response);
}
});
return false;
});
</script>
{{ Form::close() }}
`
As it is very much visible that the post is updated through a route & controller I want to have another dive and a success message at this script to be displayed after the success of posting. I am looking for some professional structure using what there is minimal need to have interaction with the server side and give user a better page viewing experience.
Thanks a lot for helping me in this research.
I am not sure if I understand you well, but if you want to notify the user about the result of an ajax-called db update you need to have
a route for the ajax save db call - it should point to a method that does the db update.
the db update method should return some value indicating the success/failure of update (for example OK or FAIL)
the only result of calling the method will be just plain text page with OK or FAIL as body
fetch the result by ajax and inform user accordingly (after form submit button)
check out the below code for ajax call itself (inside the form submit handler) to see what I mean
var db_ajax_handler = "URL_TO_YOUR_SITE_AND_ROUTE";
var $id = 1; //some id of post to update
var $content = "blablabla" //the cotent to update
$.ajax({
cache: false,
timeout: 10000,
type: 'POST',
tryCount : 0,
retryLimit : 3,
url: db_ajax_handler,
data: { content: $content, id: $id }, /* best to give a CSRF security token here as well */
beforeSend:function(){
},
success:function(data, textStatus, xhr){
if(data == "OK")
{
$('div.result').html('The new Question has been created');
}
else
{
$('div.result').html('Sorry, the new Question has not been created');
}
},
error : function(xhr, textStatus, errorThrown ) {
if (textStatus == 'timeout') {
this.tryCount++;
if (this.tryCount <= this.retryLimit) {
//try again
$.ajax(this);
return;
}
return;
}
if (xhr.status == 500) {
alert("Error 500: "+xhr.status+": "+xhr.statusText);
} else {
alert("Error: "+xhr.status+": "+xhr.statusText);
}
},
complete : function(xhr, textStatus) {
}
});
EDIT: as per comment, in step 2 (the method that is called with AJAX) replace
if($s)
{
return Redirect::route('questions.index') ->with('flash', 'The new Question has been created');
}
with
return ($s) ? Response::make("OK") : Response::make("FAIL");
EDIT 2:
To pass validation errors to the ajax-returned-results, you cannot use
return Response::make("FAIL")
->withInput()
->withErrors($s->errors());
as in your GIST. Instead you have to modify the suggested solution to work on JSON response instead of a plain text OK/FAIL. That way you can include the errors in the response and still benefit from the AJAX call (not having to refresh the page to retrieve the $errors from session). Check this post on the Laravel Forum for a working solution - you will get the idea and be able to fix your code.

Categories