I have that Form (extending AbstractType):
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('files', FileFieldType::class, [
'label' => 'Files',
'multiple' => true]
);
}
This tiny form in the frontend (ReactJS):
<form onChange={onChange} ref={node => form = node}>
<input type="file" multiple={multiple} name="file[files]" />
</form>
I the upload is triggered the following happens:
const data = new FormData(form);
fetch('/upload', {
method: 'POST',
headers: {
'Content-Type': 'multipart/form-data'
},
body: data
});
But on the server no files arrive, so in the controller:
$request->files->all(); //[]
and thus the form is never valid, too.
In a functional test I am using this:
$client->request('POST', '/upload', [], ['file' => ['files' => $file]]);
where $file refers to an Object of type UploadedFile. That works, so what is the error here?
As I could find in this answer:
The basic idea is that each part (split by string in boundary with --) has it's own headers (Content-Type in the second part, for example.) The FormData object manages all this for you, so it's a better way to accomplish our goals.
So to make the upload work, I needed to drop the content-type from the headers and rename the input field to: file[files][].
Related
I am facing CSRF token mismatch problem in laravel. I have checked all notes from stackflow and other sites also but not able to clear this problem.
https://mybestlife.mg-wellness.com/admin/login
user : admin#gmail.com
pass : 1234
you can check the error in console.
Ajax
$("#loginform").on('submit', function(e){
e.preventDefault();
$('button.submit-btn').prop('disabled', true);
$('.alert-info').show();
$('.alert-info p').html('Authenticating...');
$.ajax({
type:"POST",
url:$(this).prop('action'),
data:new FormData(this),
headers: headers,
dataType:'JSON',
contentType: false,
cache: false,
processData: false,
success: function(data) {
console.log(data);
if ((data.errors)) {
$('.alert-success').hide();
$('.alert-info').hide();
$('.alert-danger').show();
$('.alert-danger ul').html('');
for(var error in data.errors) {
$('.alert-danger p').html(data.errors[error]);
}
} else {
// console.log(data)
$('.alert-info').hide();
$('.alert-danger').hide();
$('.alert-success').show();
$('.alert-success p').html('Success !');
window.location.href = data;
}
$('button.submit-btn').prop('disabled',false);
}
});
});
Login function
public function doLogin(Request $request)
{
// print_r($request->all());
$rules = [
'email' => 'required|email',
'password' => 'required'
];
$validator = Validator::make($request->all(), $rules);
if ($validator->fails()) {
return response()->json(array('errors' => $validator->getMessageBag()->toArray()));
}
//--- Validation Section Ends
// Attempt to log the user in
if (Auth::guard('web')->attempt([
'email' => $request->email,
'password' => $request->password,
'status' => 1,
'role' => 1,
'level' => 0
], $request->remember)) {
// if successful, then redirect to their intended location
return response()->json(route('dashboard'));
}
// if unsuccessful, then redirect back to the login with the form data
return response()->json(array('errors' => [
0 => 'Credentials Doesn\'t Match !'
]));
}
Code is working perfectly on localhost and my testing server. But not on the server, i shared above.
Please help me to over come this problem.
Thanks
I think you're missing a header. That's how I've always passed the CSRF token when I use ajax.
The following should be in your resources/js/bootstrap.js file.
window.$ = window.jQuery = require('jquery');
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
});
When trying to login using your site, I couldn't see the X-CSRF-TOKEN header in the request.
I think you didn't set the APP_URL's value correctly. It should be
APP_URL=https://mybestlife.mg-wellness.com instead of what you currently have. (APP_URL=http://localhost/mybestlife_mg_wellness/)
(run php artisan config:clear after changing .env file)
Your site has debug mode on and an unrelated error about the route 'user_login' not existing, this exposes your whole configuration. Please take care to update your database credentials, they are compromised.
This is very important.
Also, rerun the command php artisan key:generate to update the APP_KEY as well.
you have to add #csrf in your form
<form method="post" action="javascript:void(0)" enctype="multipart/form-data">
#csrf
</form>
also add header in jquery
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
also add this meta tag in head of page
<meta name="csrf-token" content="{{ csrf_token() }}">
then you will never get token error .
Add a below line in data array
data:{
_token : {{csrf_field()}},
name:name
}
I am working on Yii 1 application. In my application, there is a CGridView where there is a link, which also fires an ajax request on onclick event. I am sending id as parameter. But the ajax return 400 Bad Request error. Please help me in this matter.
Here is the Gridview:
<h3>Civil Cases</h3>
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id'=>'notifications-grid',
'dataProvider'=>$dataProvider_civil,
'summaryText' => false,
'columns'=>array(
array(
'name' => 'case_id',
'type' => 'raw',
'value' => 'CHtml::link(CHtml::encode($data->case_id),array("civilcases/view","id"=>$data->case_id), array("onclick"=>"js:readNotification($data->id)"))'
),
array(
'name' => 'caseno',
'type' => 'raw',
'value' => 'CHtml::link(CHtml::encode($data->caseno),array("civilcases/view","id"=>$data->case_id), array("onclick"=>"js:readNotification($data->id)"))'
),
'date_filing',
'next_date',
'panel_lawyer_id',
),
));
?>
here is the script:
<script>
var readNotification = function(id) {
console.log("button clicked with ID: "+id); //getting id here
$.ajax({
type:'POST',
url:'<?php echo Yii::app()->createUrl("notifications/readNotification");?>',
data: {id: id}
});
};
</script>
here is the controller:
public function actionReadNotification(){
echo $_POST['id'];
}
added readNotification function to the accessRules. When clicking on the link new page is loading but ajax request shows error.
Try adding the csrf token inside your data with your ajax request.
<script>
var readNotification = function(id) {
console.log("button clicked with ID: "+id); //getting id here
$.ajax({
type:'POST',
url:'<?php echo Yii::app()->createUrl("notifications/readNotification");?>',
data: {id: id,<?=
Yii::app()->request->csrfTokenName?>:<?=Yii::app()->request->csrfToken?>,}
});
};
</script>
You can also disable the csrftoken by adding the below in the beforeAction()
public function beforeAction($action) {
if($action->id=='readnotification'){
$this->enableCsrfValidation = false;
}
return parent::beforeAction($action);
}
but this is not recommended way of doing the work.
EDIT
i mistakenly added Yii::$app->request instead of Yii::app()->request as the first one is for Yii2 and not for Yii1 please change it to
<?=Yii::app()->request->csrfTokenName?>:<?=Yii::app()->request->csrfToken?>
and make sure you have the request component with the following configurations
'components'=>array(
.
.
.
'request'=>array(
'enableCookieValidation'=>true,
'enableCsrfValidation'=>true,
'csrfTokenName'=>'_my-token',
),
Note : you can change the _my-token to any other name you like
please help me.
I've been working recently in Codeigniter form validation without using AJAX and working fine, i just need to add $form_error to each field and everything just put on there. So, i am not good in javascript and really confusing how to show the errors response to each input field because when i am using AJAX the only idea i have is putting the response in a selector like $(#error-info)
This is my work so far
in my controller
$this->_rules();
if($this->form_validation->run() == FALSE)
$msg = array(
'name' => form_error('name'),
'phone' => form_error('phone'),
'email' => form_error('email')
);
echo json_encode($msg);
and my ajax :
<script type="text/javascript">
$(document).ready(function() {
$('#frm').submit(function(){
$.post($('#frm').attr('action'), $('#frm').serialize(), function( data ) {
console.log(data);
}, 'json');
return false;
});
});
</script>
the response look like this
{"name":"<small class=\"text-danger\">The name field is required.<\/small>","phone":"<small class=\"text-danger\">The phone field is required.<\/small>","email":"<small class=\"text-danger\">The email field is required.<\/small>"}
Please give me a hint. What a possible ways to do this?
Something like this should work (haven't tested):
PHP
$msg = array(
'name' => form_error('name'),
'phone' => form_error('phone'),
'email' => form_error('email')
);
echo json_encode(array('status' => 'error', 'response' => $msg));
AJAX
We assume that the indexes of the $msg array matches an actual id e.g. id='email' so we can propagate the error messages after the field.
$(document).ready(function () {
$('#frm').submit(function () {
$.post($('#frm').attr('action'), $('#frm').serialize(), function (res) {
var data = JSON.parse(res);
if (data.status == 'error') {
$.each(data.response, function(item_id, item_error_msg) {
$('#'+item_id).after().html(item_error_msg);
});
} else {
alert(data.response);
}
}, 'json');
return false;
});
});
I am working in laravel 5. and using blade and ajax for upload image.
Every thing was working fine unless I inserted validation code in store function inside controller. Getting server error:
POST http://localhost:8000/imgC 500 (Internal Server Error)
I guess there is something wrong with url inside ajax or in routes, I am using Restfull Controller.
image.blade.php
{{Form::open(array('url' => 'imgC', 'method' => 'post','files'=>true, 'id'=>'upload_form'))}}
Title: {{Form::text('title')}}
Image: {{Form::file('image')}}
{{Form::submit('submit',['id' => 'btnAddProduct'])}}
{{Form::close()}}
ImageController.php:
public function store(Request $request)
{
$validator = Validator::make($request->all(), [
'name' => 'required|max:255',
]);
if ($validator->fails()) {
return "error";
}
$destinationpath = public_path() . '/img/';
$image=$request->input('image');
$filename=$request->file('image')->getClientOriginalName();
$request->file('image')->move( $destinationpath,$filename );
$img= new Image;
$img->name= $request->input('title');
$img->picture_path=$filename;
$saveflag=$img->save();
if($saveflag){
return Response::json(['success' => $saveflag, 'file' => asset($destinationpath.$filename)]);
}
}
AJAX function:
$(document).ready(function() {
$('#upload_form').submit(function (event) {
event.preventDefault();
$.ajax({
url: '/imgC',
data: new FormData($(this)[0]),
type: "POST",
processData: false,
contentType: false
}).done(function (response) {
console.log(response);
$("#success").show();
setTimeout(function() { $("#success").hide(); }, 5000);
});
});
});
route.php:
Route::resource('imgC', 'ImageController');
What am I doing wrong here?
I looked into the server log files and figured it out.
There was error with validation after adding Use Validator; in Image controller, problem solved
controller:
public function searchAction()
{
$form = new Application_Form_Search;
$k = $form->getValue('keyword');
$car = new Application_Model_Car();
$mapper = new Application_Model_CarMapper();
$this->view->cars = $mapper->search($keyword);
}
form
<?php
class Application_Form_Search extends Zend_Form {
public function init(){
$this->setMethod('post');
$this->addElement('text', 'keyword', array(
'required' => true,
'label' => 'Keyword:'
));
$this->addElement('button', 'submit', array(
'required' => false,
'ignore' => true,
'label' => 'Search'
));
}
}
?>
original view page
$(document).ready(function(){
$("#submit").click(function(){
$("#main").load('/cars/search');
});
});
Here I am trying to return the search view at the "id=main" section in the original view page by using .load()
In the search view, <?=$this->keyword?> is showing null
it seems like there's problem fetching the keyword field from the form
Ok, you need to set the second variable of .load to send the data. At present you aren't sending the data to the .load function
so it would be more like this. This is assuming that you have id of keyword
$("#main").load('/cars/search', {'keyword':$('input#keyword').val()});
or you could use
$("#main").load('/cars/search', {'keyword':$('[name="keyword"]').val()});
Please see
http://api.jquery.com/load/
Also remember to escape the value so people can't send malicious code through your form.
Hope that helps