Laravel Validation redirect after ajax call - php

I have a fresh 5.3 installation and want to make api calls with postman. I also tried it with angular2 to make sure it's not a problem with postman.
In my routes/api.php I got a simple route:
Route::post('test', function(\App\Http\Requests\LoginRequest $request) {
return $request->all();
});
LoginRequest is checking if the fields email and password are there. If so, the output is as excepted. But when it's missing it redirects to /.
Do I have to add some information for form validation for ajax calls? I thought laravel would return a json error object when there is an ajax call.
Update:
I found out that I missed the Accept application/json header in Postman. With it it works finde. But is there a way to say that all api/* calls should be treated as a json call?

I created a new parent class for my Requests. It checks if the route belongs to the api group or not. I tried to add a Middleware to the group to add the header, but this trick failed.
class JsonRequest extends FormRequest
{
public function expectsJson()
{
return ($this->route()->getAction()['middleware'] == 'api');
}
}

You can response to ajax call like this
return response()->json(array('error' => $validator->getMessageBag()->toArray()), 400);
response status 400 indicates error and you will get in error section
error: function(jqXHR, textStatus, errorThrown){
var errResponse = JSON.parse(jqXHR.responseText);
if (errResponse.error) {
$.each(errResponse.error, function(index, value)
{
console.log(value);
});
}
}

Related

axios delete route not supported laravel vuejs

I have a very strange issue with deleteing records. In my vuejs I call axios.delete to delete my record, which in turn calls my laravel route.
The record is getting deleted fine but an error message is displaying "message": "The DELETE method is not supported for this route. Supported methods: GET, HEAD.",
axios.delete('/member/event/' + this.data.module.slug);
My laravel route is as follows
Route::resource('event', 'EventController');
I am using laravel 6 to
It's high chance that delete url you try to send and route url are not the same, please check network and route:list, if not then you probably define your spa route at top, I mean the route except every params
The issue was nothing to do with the routes it was that I was not returning a json response after the delete which was causing the issue
Try this way-
routes routes/api.php
Route::apiResource('event','EventController');
In Controller Method
public function destroy(Event $event)
{
$event->delete();
return new EventResource($event);
}
In Your Components
axios.delete('/api/event/'+this.data.module.slug)
.then(response => {
console.log(response)
this.$snotify.success("Data Successfully Delete",'Success')
})
.catch(err => {
console.log(err)
})

Laravel API and Ionic 2 Client: CORS No 'Access-Control-Allow-Origin' header

I created an API with Laravel and I try to use it with an Ionic 2 project
I'm trying to make a GET request to my Laravel API.
When I make my http request to
auth/{prodiver}/callback/{userID}/{accessToken}
I got this error:
Failed to load http://api.url.net/api/auth/facebook/callback/XXXX/MY_TOKEN: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8001' is therefore not allowed access.
My route looks like this:
Route::group(['middleware' => ['guest', 'cors']], function() {
Route::get('test', function () {
return response()->json('{dummy.data}', 200);
});
Route::get('auth/{prodiver}/callback/{userID}/{accessToken}', 'SocialAuthController#callback')->middleware('cors')->name('social.auth'); // social auth
});
But when I try the same code, with the route test, it works and I got the data...
The "facebook connect" isn't the problem, the success callback is triggered.
Here is the callback() method
public function callback($provider, $userID, $accessToken)
{
if ($provider == "facebook"){
$user = $this->createOrGetUser($userID, $accessToken);
auth()->login($user);
return response()->json($user, 200);
}
}
All other http requests works perfectly...
Here is the concerned http request (in Ionic project)
let headers = new Headers();
headers.append('Content-Type', 'application/json');
let url = this.baseApiUrl+'auth/facebook/callback/' + userID + '/' + accessToken;
this.http
.get(url, {headers: headers})
.map(res => res.json())
.subscribe(data => {
console.log(data)
}, err => {
this.onError(err);
}
);
I don't understand what's going on, anyone has a clue ? I'm totally tired of this error :/
Thanks a lot! :)
First, why do you set cors middleware when defining the second route? It is already set for the whole group.
Second, cors returns a cors error in case you have some error in your code, that's its behaviour.
When an error occurs, the middleware isn't run completely. So when
this happens, you won't see the actual result, but will get a CORS
error instead.
Try to debug your code to find a bug. Test returns data, it means that this is not the cors who gives the error, it is your code.

Laravel 5 making DELETE request by ajax - method not allowed

I'm trying to make a DELETE request within a Laravel app using ajax
I have a function to make the request - using the right verb - to a resource but keeps coming up method not allowed:
Here's my ajax request:
$.ajax({
type: 'DELETE',
url:'/user/58',
data: {
'_method': 'DELETE',
'id': id
},
dataType: 'json',
success: function (data) {
// do something with ajax data
if (data.result) {
return true;
}
return false;
},
error: function (xhr, ajaxOptions, thrownError) {
console.log('error...', xhr);
return false;
//error logging
},
complete: function () {
//afer ajax call is completed
}
});
id is supplied within a function and for the test is 58.
Watching the network panel in Chrome I can see it starts with the expected url of user/58 but then quickly gets shortened to user
I know that to get the resource route to pick up the request it needs to be user/58 and the method DELETE so it will go to the destroy method and because of this it is being routed to the Index method which expects a GET request hence the method not allowed.
Why is my request url being changed?
What is the correct approach to make a DELETE request in Laravel?
Thanks
Edit:
Here's my route:
Route::group( [ 'middleware' => [ 'auth' , 'admin' ] ] , function ()
{
Route::resource( 'user' , 'UserController' );
} );
The csrf token is being taken care of in the headers - fairly certain this isn't the cause of problem as I do not get an invalid token exception
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
Thanks
Two possible things that can happen here, I need to write this in a longer post than a comment so hopefully I got it right.
First thing that pops in my mind is an auth check that fails while doing the ajax request. At least I would redirect you back to the main resource if you wouldn't have enough rights.
However, my second guess is maybe even more likely. Have you thought of the X-CSRF-TOKEN that you need to send with an ajax request? See https://laravel.com/docs/5.2/routing#csrf-x-csrf-token
From the docs:
In addition to checking for the CSRF token as a POST parameter, the Laravel VerifyCsrfToken middleware will also check for the X-CSRF-TOKEN request header. You could, for example, store the token in a "meta" tag:
<meta name="csrf-token" content="{{ csrf_token() }}">
Once you have created the meta tag, you can instruct a library like jQuery to add the token to all request headers. This provides simple, convenient CSRF protection for your AJAX based applications:
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});

laravel 5.2 valid ajax request

How can we check in Laravel 5.2 if a request is a valid ajax request. In codeigniter ,we could check it like $this->input->is_ajax_request(). Does, Laravel 5.2 has something similar?
Also, I would like to know that how can we validate a request for csrf token. Is it fine if I let my webpage render through the 'web' middleware generating a csrf token and then pass this token as ajax request parameter? Would Laravel take care of validating the token or is there an alternate way around this?
I have checked the laravel 5.2 documentation, and since this is the first time I am dealing with laravel framework, it seems like the documentation assumes that the reader already has a familiarity with earlier versions of the framework. To a new comer like me this is little overwhelming.
Thanks in advance. Please let me know if you need more inputs from me.
Prakhar
I think this may help you to undestand a very basic way of using AJAX with Laravel.
It's a really old piece of code, but it works jajajaja
Controller side:
/**
* #param Request $request
* #return \Illuminate\Http\JsonResponse
*/
public function getRamos(Request $request)
{
$check = Ramo::find($request->input('ramo'));
$subramos = Subramo::where('ramo_id', $check->id)->get(['nombre_subramo']);
if($request->ajax()){
return response()->json([
'subramos' => $subramos
]);
}
}
In the front:
<script>
$(document).ready(function(){
$('#ramo').change(function(){
var ramo, token, url, data;
token = $('input[name=_token]').val();
ramo = $('#ramo').val();
url = '{{route('getRamos')}}';
data = {ramo: ramo};
$('#subramos').empty();
$.ajax({
url: url,
headers: {'X-CSRF-TOKEN': token},
data: data,
type: 'POST',
datatype: 'JSON',
success: function (resp) {
$.each(resp.subramos, function (key, value) {
$('#subramos').append('<option>'+ value.nombre_subramo +'</option>');
});
}
});
});
});
</script>
Considering "#ramo" as a select input and in use of the style / html package where the token is passed as a hidden input.
In Laravel 5.2 (I hope any body get help from this code for Ajax)
Get ajax request in function , two examples of function is under:
First Example
public function getLev() {
if (!Request::ajax())
return false;
$result = Input::all();
$lev_id = (int) $result['lev_id'];
$invoiceid = (int) $result['invoiceid'];
return SuppliersController::getLev($invoiceid,$lev_id);//you can do any thing with your variables
//function is working in my case, you case take idea from this function
}
Second Example
public function deleteInvoice() {
if (Request::ajax()) {
$data = Input::all();
return delete_invoice($data['invoice_id'], $data['reason_text']);//you can do any thing with your variables
}
return false;
//function is working in my case, you case take idea from this function
}
Include these files on top of the page/controller where you write above ajax related functions:
use Illuminate\Support\Facades\Input;
use Illuminate\Support\Facades\Request;
How can we check in Laravel 5.2 if a request is a valid ajax request. In codeigniter ,we could check it like $this->input->is_ajax_request(). Does, Laravel 5.2 has something similar?
The Request class has an ajax() function, so $request->ajax() or Request::ajax() (depending on how you're getting the request in your controller) will do the trick.
Also, I would like to know that how can we validate a request for csrf token. Is it fine if I let my webpage render through the 'web' middleware generating a csrf token and then pass this token as ajax request parameter? Would Laravel take care of validating the token or is there an alternate way around this?
Yes, pass the token with the AJAX call and make sure your routes have the CSRF middleware (try a request without a token - it should throw an error). Examples are in the docs for this: https://laravel.com/docs/5.2/routing#csrf-x-csrf-token
Anytime you define a HTML form in your application, you should include a hidden CSRF token field in the form so that the CSRF protection middleware will be able to validate the request.
To generate a hidden input field _token containing the CSRF token, you may use the csrf_field helper function:
So to use AJAX request with POST method, you need to pass hidden CSRF token field along with ajax data:
<script>
var token="<?php echo csrf_token(); ?>";
$.ajax({
url:url,
method:'POST',
data:{
'_token':token,
'id':1
}
})
</script>

jQuery POST request always returns 404 not found with Laravel 4

Every time I try to make a POST request with jQuery I keep receiving back the 404 error.
This is the UserController.php:
class UserController extends BaseController {
public function signUp($username, $password, $email) {
$user = new User();
$user->setUsername($username);
$user->setPassword($password);
$user->setEmail($email);
return 'OK';
}
}
And this is the routes.php:
Route::get('/signup', function(){
return View::make('signup');
});
Route::post('/signup/{username}/{password}/{email}', 'UserController#signUp');
I always receive this error:
POST http://192.168.0.102/webname/public/signup 404 (Not Found)
Why is that? If I try to navigate to http://192.168.0.102/webname/public/signup the page is loaded and the signup form is shown.
You're are using a "GET" type route.
Let me explain.
If you want to use a route like /route/{something}/{different}
you have to manualy generate an URL matching that route.
URL::route('route', $something, $different)
Variable passed thought POST method are only available in the HTTP Headers.
So you can't call Route::post('/route/{variable}') by passing variable though POST method.
Only with Route::get().
To get your variable with POST use
Input::get('your_variable_name')
in your controller action.
Sorry for my bad english... A little bit tired, and I'm french too !
You are defining
Route::post('/signup/{username}/{password}/{email}', 'UserController#signUp');
But trying to access: /webname/public/signup.
That pattern does not exist for POST, but just for GET.
I had some troubles that were related to this discussion and in my opinion did not merit their own post: jQuery post requests kept getting handled by my Laravel get controller.
My routes:
Route::controller('/test','TestController');
In my view :
<script>
$(document).ready(function() {
jQuery.ajax({
type:'post',
url: '/test/x/',
success: function (response) {
alert(response);
}
});
});
</script>
My Controller:
public function getX() {
return 'Get';
}
public function postX() {
return 'Post';
}
On page load, I expected to see an alert reading "Post"... but instead I kept seeing "Get". Laravel was routing the post request to the get controller.
Solving this had to do with the trailing slash. Apparently, Laravel interpreted "/test/x/" as a GET route, but "/test/x" as a POST route. So the lesson is that Laravel routing can be subtle. Hope that helps clarify the discussion a bit.

Categories