I try on my laravel project to create a form that upload a image on the server using ajax but the request always failed, I try to do this is there any problem in code ?
html:
<form id="changeImage" enctype="multipart/form-data">
<input type="hidden" name="_token" id="_token" value="{{csrf_token() }}">
<center>
<div class="form-group">
<center><input type="file" name="image" accept="image/*"></center>
<p class="help-block">Format: png, jpg et gif.</p>
</div>
</center>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
Ajax:
$('input[name="image"]').change(function(event) {
files = event.target.files;
});
$('#changeImage').submit(function(event) {
event.preventDefault();
var _token= $('input[name="_token"]').val();
var data = new FormData();
data.append('_token',_token);
$.each(files, function(k, v) {
data.append('image',v);
});
$.ajax({
url: '/profile/image',
type: 'POST',
data:data,
processData: false,
contentType: "multipart/form-data",
success: function(data){
console.log('done'+data);
},
async: false,
error: function(data){
console.log('No');
var errors = data.responseJSON;
errorsHtml = '<div class="alert alert-danger"><ul>';
$.each( errors , function( key, value ) {
errorsHtml += '<li>' + value[key] + '</li>';
});
errorsHtml += '</ul></div>';
$( '#form-errors' ).html( errorsHtml );
}
});
});
Server Side - PHP (laravel):
Route:
Route::post('profile/image','ProfileFormsController#postImage');
Controller
public function postImage(Request $request){
if($request->ajax()){
$imagedestination = 'images\profile';
$file = $request->file('image');
$image_name = time()."-".$file->getClientOriginalName();
$file->move($imagedestination, $image_name);
}
}
You forgot about CSRF validation.
As far as this request is POST, you have to send also CSRF token, or, at least, disable check for this route.
Go to app/Http/Middleware/VerifyCsrfToken.php
and add your POST-url to protected $except = [];
Also read this part of documentation: https://laravel.com/docs/master/routing#csrf-protection
Related
In his life, he only encountered an ajax 2 times and here again our paths intertwined with him and he gave me 422 errors. I googled and realized that 422 error is a validation error, but in what specific place the error, I just can not understand.
This is my script
<script type="text/javascript">
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$( "#form" ).submit(function( e ) {
e.preventDefault();
var message = $('#message').val();
var img = $('#img').val();
var user_id = $('#user_id').val();
$.ajax({
type: "POST",
url: "{{route('profile.store', ['id' => Auth::user()->id])}}",
data: {message:message, img:img, user_id:user_id},
success: function (data) {
$("#textpost").html($(data).find("#textpost").html());
},
});
});
</script>
And my method
public function store(Request $request) {
$validator = $this->validate($request,[
'message' => 'required|max:1000',
'img' => 'mimes:jpeg,png,gif|max:3000',
]);
if($validator ) {
$post = new Profile();
$post->message = $request->message;
$post->user_id = Auth::user()->id;
if($request->file('img')) {
$path = Storage::putFile('public', $request->file('img'));
$url = Storage::url($path);
$post->img = $url;
}
$post->save();
}
return redirect()->back();
}
And my form
<div class="card-header">
<div class="input-group">
<form action="{{route('profile.store', ['id' => Auth::user()->id])}}" method="post" enctype="multipart/form-data" id="form">
#csrf
<textarea class="form-control" id="message" name="message" cols="100" rows="4" placeholder="О чем думаешь?"></textarea>
<input type="file" id="img" name="img" value="Прикрепить изображение" class="mt-2">
<div class="text-right">
{{-- <input type="submit" id="btn" value="Отправить" class="btn btn-outline-dark btn-sm mt-4">--}}
<button type="submit" id="btn" class="btn btn-outline-dark btn-sm mt-4">Отправить</button>
</div>
</form>
</div>
</div>
$validator = $this->validate($request,[
'message' => 'required|max:1000',
'img' => 'mimes:jpeg,png,gif|max:3000',
]);
This portion of your code throws a validation errors exception which returns 422.
If you wish to handle validation on your own, try this logic instead:
$validator = validator($request->all(), [
'message' => 'required|max:1000',
'img' => 'mimes:jpeg,png,gif|max:3000',
]);
if($validator->fails()) {
// return as appropriate
return response()->son($validatior->errors(), 422);
}
// rest of your code
There is a problem with your Ajax call, because you are uploading text and file at the same time you can pass it through FormData. You were also missing
contentType: false,
processData: false,
Here is the updated ajax call:
<script type="text/javascript">
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$( "#form" ).submit(function( e ) {
e.preventDefault();
var formData = new FormData(this); //set formData to selected instance
var message = $('#message').val();
var img = $('#img').val();
var user_id = $('#user_id').val();
$.ajax({
type: "POST",
url: "{{route('profile.store', ['id' => Auth::user()->id])}}",
data: formData, //pass to our Ajax data to send
success: function (data) {
$("#textpost").html($(data).find("#textpost").html());
},
contentType: false,
processData: false,
});
});
</script>
Setting processData makes it so your FormData is not converted to a string. Setting contentType to false is used for forms that pass files, when false, no header will be added to the request, which is exactly what we want when submitting multipart/form-data.
I am trying to pass a file object with multiple attribute via AJAX in my WordPress application but not being able to capture them in the process function.
HTML:
<form enctype="multipart/form-data" method="post">
<input type="text" id="album_title" name="album_title" />
<input type="file" multiple" id="photo_upload" name="photo_upload[]" class="files-data" />
<input type="button" value="Submit" onclick="uploadPhoto();" />
</form>
JS:
var formData = new FormData();
formData.append('album_title', jQuery('#album_title').val());
formData.append('security', mbAlbumUploader.ajax_nonce);
jQuery.each(jQuery('.files-data'), function(i, obj) {
jQuery.each(obj.files, function(j, file){
formData.append('files[' + j + ']', file);
});
});
jQuery.ajax({
url: 'mbAlbumUploader.ajax_url,'
type: 'post',
data: formData,
dataType: 'json',
processData: false,
contentType: false,
success: function(response) {
alert(response.files);
}
});
PHP function:
function uploadPhoto() {
$fileName_str = '';
foreach($_FILES['photo_upload']['name'] as $f=>$name) {
$extension = pathinfo($name, PATHINFO_EXTENSION);
$fileName_str .= $name . ', ';
}
die(wp_json_encode(array(
'files' => $fileName_str;
)));
}
What I am doing wrong?
Try to run ajax request by click event or submit event. I made few changes this is script below. Assuming your button has update class.
HTML
<form enctype="multipart/form-data" method="post">
<input type="text" id="album_title" name="album_title" />
<input id="file" name="file[]" type="file" multiple/>
<input class="update" type="submit" />
</form>
JavaScript
$(".update").click(function(e) {
// Stops the form from reloading
e.preventDefault();
$.ajax({
url: 'upload.php',
type: 'POST',
contentType:false,
processData: false,
data: function(){
var data = new FormData();
data.append('album_title', jQuery('#album_title').val());
data.append('security', mbAlbumUploader.ajax_nonce);
jQuery.each(jQuery('#file')[0].files, function(i, file) {
data.append('file-'+i, file);
});
data.append('body' , $('#body').val());
data.append('uid', $('#uid').val());
return data;
}(),
success: function(result) {
alert(result);
},
error: function(xhr, result, errorThrown){
alert('Request failed.');
}
});
$('#picture').val('');
$('#body').val('');
});
PHP (upload.php)
You can Access your files from $_FILES global.
I'm trying to submit a single value as following?
HTML:
<form class="form-horizontal" role="form" method="POST" enctype="multipart/form-data" name="frmanalyse" id="frmanalyse">
{{ csrf_field() }}
<label for="marginsource" style="float: left; width:150px; text-align:left;">Margin Source</label>
<input type="file" name="marginsource" id="marginsource" >
<br />
</form>
script:
<script type="text/javascript">
$( "#frmanalyse" ).submit(function(event) {
$.post( "marginanalyser", {username: "medo ampir"}, function( data ) {
alert(data);
});
event.preventDefault();
});
in laravel routes:
Route::post('marginanalyser',function(Request $request){
echo $request->input('username');
$file = $request->file('marginsource');
echo 'File Name: '.$file->getClientOriginalName();
});
nothing shows in the message at all.
Change your JavaScript to use FormData as you aren't submitting the file
$( "#frmanalyse" ).submit(function(event) {
event.preventDefault();
var formData = new FormData();
formData.append('marginsource', $('#marginsource')[0].files[0]);
formData.append('username', "medo ampir");
$.ajax({
url : window.location.origin + "/marginanalyser",
type: "POST",
data : formData,
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
processData: false,
contentType: false,
success:function(data, textStatus, jqXHR) {
console.log(data);
},
error: function(jqXHR, textStatus, errorThrown){
//if fails
}
});
});
This is probably repost as I might not searched deep enough in stackoverflow, though a few posts that I found haven't helped me enough. So I'm trying to do a simple thing - upload an image using ajax. I've got this HTML:
<form class="form-inline" id="navigationLinkCreationForm" >
<input type="text" class="form-control" placeholder="Nuorodos pavadinimas" id="linkName" />
<label class="btn btn-default btn-file">
Įkelti ikoną(1:1)<input id="selectNavigationIcon" name="navigationIcon" type="file" style="display: none;">
</label>
<input type="submit" class="btn btn-success" id="createLinkButton" value="Sukurti nuorodą" />
</form>
Then I've got this ajax:
$('#createLinkButton').on('click', uploadFiles);
function uploadFiles(event)
{
event.preventDefault();
var formData = new FormData($('#navigationLinkCreationForm'));
$.ajax({
type: 'POST',
url: '../php_includes/uploadNavigationIcon.php',
data:formData,
success: function (data)
{
console.log(data);
},
processData: false,
contentType: false,
cache: false
});
}
And finally I've got a simple uploadNavigationIcon.php file which just outputs "S" if files have been submitted
<?php
if(isset($_GET['files']))
{
echo "S";
}
After running this I'm just getting empty output, which just means that files weren't submitted.
Try this, its a tested and working code:
$(document).ready(function(){
$('#upload').on('click', function() {
var file_data = $('#pic').prop('files')[0];
var form_data = new FormData();
form_data.append('file', file_data);
$.ajax({
url : 'upload.php', // point to server-side PHP script
dataType : 'text', // what to expect back from the PHP script, if anything
cache : false,
contentType : false,
processData : false,
data : form_data,
type : 'post',
success : function(output){
alert(output); // display response from the PHP script, if any
}
});
$('#pic').val(''); /* Clear the file container */
});
});
upload.php
<?php
if ( $_FILES['file']['error'] > 0 ){ // file data can't be fetched by using $_GET
echo 'Error: ' . $_FILES['file']['error'] . '<br>';
}
else {
if(move_uploaded_file($_FILES['file']['tmp_name'], 'uploads/' . $_FILES['file']['name']))
{
echo "File Uploaded Successfully";
}
}
?>
I've create one form which is given below
html code:
<form method="post" class="inline" id="upload_form" enctype="multipart/form-data">
<input style="margin-top:0px;" type="file" name="data1" id="file1" class="btn btn-block btn-primary"/>
<input type="hidden" name="_token" value="{{ csrf_token() }}" id="token">
link submit
</form>
ajax code:
function create()
{
alert();
var file = document.getElementById('file1');
var token = document.getElementById('token').value;
var data1 = new FormData($("#upload_form")[0]);
var route = "http://localhost:8080/form";
console.log(FormData);
console.log(data1);
$.ajax({
type:'POST',
url: route,
headers: {'X-CSRF-TOKEN': token},
contentType: false,
processData: false,
data:{
'data1': data1,
},
success:function(e){
if(e == 0)
{
alert("Success Full Created");
}
else
{
alert("Error");
}
}
});
}
This is my route :
Route::post('form', 'StoreController#newstore');
I've created controller which is given below
Controller :
public function newstore(Request $request)
{
$post = $request->file('data1');
dd($post);
//If there is error try dd($post) and let me know
// we need know if the data file image is passing to controller
$imageName = $post->getClientOriginalName();
$imagemove= $post->move(public_path('images'),$imageName);
$data123 = array ( "photo"=> $imageName, );
$check222 = DB::table('product') -> insert($data123);
}
when i run this code its show me this error :
MethodNotAllowedHttpException in RouteCollection.php line 218:
Try this:
<form method="post" class="inline" id="upload_form" enctype="multipart/form-data">
<input style="margin-top:0px;" type="file" name="data1" id="file1" class="btn btn-block btn-primary"/>
<input type="hidden" name="_token" value="{{ csrf_token() }}" id="token">
link submit
</form>
if for example your route is:
Route::post('form', 'yourcontroller#newstore');
JS
function create()
{
var file = document.getElementById('file1');
var route = "http://localhost:8000/form";
var token = document.getElementById('token').value;
var data1 = new FormData($("#upload_form")[0]);
// we are using "$", i hope that you have jquery library
/* alternative you can do:
var getUpload = document.queryselector('#upload_form');
var data1 = getUpload[0];
*/
//if there is error try also console.log(formData)
// if error try console-log(data1); info about the file uploaded
// if error token verify console.log(token); have the token serial number
$.ajax({
type:'POST',
url: route,
headers: {'X-CSRF-TOKEN': token},
contentType: false,
processData: false,
data:{
'data1': data1,
},
success:function(e){
if(e == 0)
{
alert("Success Full Created");
}
else
{
alert("Error");
}
}
});}
var submit = document.querySelector('#submit').onclick= create
CONTROLLER
public function newstore(Request $request)
{
$post = $request->file('data1');
//If there is error try dd($post) and let me know
// we need know if the data file image is passing to controller
$imageName = $post->getClientOriginalName();
$imagemove= $post->move(public_path('images'),$imageName);
$data123 = array ( "photo"=> $imageName, );
$check222 = DB::table('product') -> insert($data123);
}
Let me know if you get some error! i hope it work!