Image upload routing issue using laravel and vue - php

I am trying to upload image but getting the error Uncaught (in promise) Error: Request failed with status code 404
Here is my code
<input type="file" id="file" class="form-control-file" v-on:change="onFileChange">
methods:{
goToLogin(){
this.upload();
},
onFileChange(e){
console.log('onFileChange');
let files = e.target.files || e.dataTransfer.files;
if(!files.length){
return;
}
this.createImage(files[0]);
},
createImage(file){
console.log('createImage');
let reader = new FileReader();
let vm = this;
reader.onload = (e) =>{
vm.image = e.target.result;
};
reader.readAsDataURL(file);
},
upload(){
console.log('upload image= '+this.image);
axios.post('/storage/images',{image: this.image}).then(response => {
console.log(response.data);
});
}
}
public function saveImage(Request $request){
$image = $request->file('image');
$filename = time() . '.' . $image->getClientOriginalExtension();
$path = public_path('images/' . $filename);
$user->image = $filename;
$user->save();
}
In upload method i am getting data in image but issue is within '/storage/images'. Can anybody please help me to fix it.

Related

Failed to load resource: the server responded with a status of 403 when using ajax to send post request on production server laravel

I am using ajax to send a request to a laravel controller with multiple images and other,
Everything work on local environement but when I upload to the production environement, the upload fails with the error
Failed to load resource:/property/images/add:1 the server responded with a status of 403 ()
Here is the ajax code
$.ajaxSetup({
headers: {'X-CSRF-TOKEN': $('input[name=_token]').val()}
});
$('#images').change(function () {
event.preventDefault();
let image_upload = new FormData();
let TotalImages = $('#images')[0].files.length; //Total Images
let images = $('#images')[0];
let p_id = $('input[name=p_id]').val();
for (let i = 0; i < TotalImages; i++) {
image_upload.append('images[]', images.files[i]);
}
image_upload.append('TotalImages', TotalImages);
image_upload.append('p_id', p_id);
$.ajax({
method: 'POST',
url: '{{ route('image.add') }}',
data: image_upload,
contentType: false,
processData: false,
success: function (images) {
Swal.fire(
'Success!',
'Images uploaded successfully',
'success'
);
$('#images').reset();
},
error: function () {
Swal.fire(
'Failed!',
'An error occured please try again',
'error'
);
$('#images').reset();
}
});
});
and this is the controller code
public function store(Request $request)
{
//check if an image has been selected
if ($request->images) {
$total=$request->TotalImages;
$images = $request->images;
foreach($images as $image) {
$photo = new Photo;
$photo->p_id = $request->p_id;
$image_temp = $image;
//echo $image_temp; die;
if ($image_temp->isValid()) {
$extension = $image_temp->getClientOriginalExtension();
$filename = 'bks'.mt_rand(000, 9999999999) . '.' . $extension;
$filepath = 'uploads/property/large/' . $filename;
$webimagefilepath = 'uploads/property/small/' . $filename;
//upload the image
Image::make($image_temp)->resize(600, 600)->save($filepath);
Image::make($image_temp)->resize(200, 200)->save($webimagefilepath);
$photo->path = $filename;
$photo->alt_text = "Book sasa property image";
$photo->save();
}
}
}
return response()->json("Success");
}
I am using named routes and the name is the one used in the ajax url.
What could I be doing wrong and how can I solve it?

$request->file keeps returning tmp path

I'm trying to upload a file using laravel and vue. When i console.log() the file, I get the picture below but in the controller, I'm receiving a tmp path only.
Vue
onFileChange(e) {
ths.file = e.target.files[0];
console.log(this.file)
},
submit(){
let form= new FormData()
form.append('file', this.file)
axios.post('/api/archieve',form).then(res=>{
//
})
},
Controller
return $request->file //returns "C:\xampp\tmp\php5E67.tmp"
UPDATE
I've checked using dd($request->file('file')); and it returns the below image but the realPath is wrong. The image is stored in a different folder on my pc.
Please try add header.
onFileChange(e) {
this.file = e.target.files[0];
console.log(this.file)
},
submit() {
let form= new FormData()
form.append('file', this.file)
axios.post('/api/archieve', form, {
headers: { 'Content-Type': 'multipart/form-data' }
}).then(res=>{
//
})
},
and in you controller, check
$request->file('file');
To store file
use Illuminate\Support\Facades\Storage;
....
$file = $request->file('file');
$path = 'my-uploads'; // path or folder where to save it
$storePath = Storage::put($path, $file);
$fileName = basename($storePath); // generated file name
$filePath = $path . '/' . $fileName; // path of file in your storage

Laravel uploading file with chunk and getting FileException error

i'm trying to use pionl/laravel-chunk-upload and Resumable.js to upload large file into server
i implemented view, controller and route and now when i try to upload file i get this error:
Symfony\Component\HttpFoundation\File\Exception\FileException: The
file "XXXXXXXX" was not uploaded due to an unknown error. in file
C:\xampp\htdocs\XXX\vendor\symfony\http-foundation\File\UploadedFile.php
on line 213
and i can't fix this error:
view:
<div class="form-group">
<div class="resumable-error">
Your browser, unfortunately, is not supported by Resumable.js. The library requires support for the HTML5 File API along with file slicing.
</div>
<div class="resumable-drop">
Drop video files here to upload or <a class="resumable-browse"><u>select from your computer</u></a>
</div>
<div class="resumable-progress">
<table>
<tr>
<td style="width: 100%"><div class="progress-container"><div class="progress-bar"></div></div></td>
<td class="progress-text" nowrap="nowrap"></td>
<td class="progress-pause" nowrap="nowrap">
<img src="/assets/global_assets/images/icons/resume.png" title="Resume upload" />
<img src="/assets/global_assets/images/icons/pause.png" title="Pause upload" />
<img src="/assets/global_assets/images/icons/cancel.png" title="Cancel upload" />
</td>
</tr>
</table>
</div>
<ul class="nav nav-sidebar mb-2 resumable-list p-0 pl-3 m-0" data-nav-type="accordion"></ul>
</div>
<script>
var r = new Resumable({
target: '/panel/uploadRadioChannelFile',
chunkSize: 1 * 1024 * 1024,
testChunks: false,
throttleProgressCallbacks: 1,
headers:{
'X-CSRF-Token' :"{{ csrf_token() }}"
},
query:{
_token : "{{ csrf_token() }}"
}
});
// Resumable.js isn't supported, fall back on a different method
if (!r.support) {
$('.resumable-error').show();
} else {
// Show a place for dropping/selecting files
$('.resumable-drop').show();
r.assignDrop($('.resumable-drop')[0]);
r.assignBrowse($('.resumable-browse')[0]);
// Handle file add event
r.on('fileAdded', function (file) {
// Show progress pabr
$('.resumable-progress, .resumable-list').show();
// Show pause, hide resume
$('.resumable-progress .progress-resume-link').hide();
$('.resumable-progress .progress-pause-link').show();
// Add the file to the list
$('.resumable-list').append('<li class="nav-item resumable-file-' + file.uniqueIdentifier + '">Uploading <span class="resumable-file-name"></span> <span class="resumable-file-progress"></span>');
$('.resumable-file-' + file.uniqueIdentifier + ' .resumable-file-name').html(file.fileName);
// Actually start the upload
r.upload();
});
r.on('pause', function () {
// Show resume, hide pause
$('.resumable-progress .progress-resume-link').show();
$('.resumable-progress .progress-pause-link').hide();
});
r.on('complete', function () {
// Hide pause/resume when the upload has completed
$('.resumable-progress .progress-resume-link, .resumable-progress .progress-pause-link').hide();
});
r.on('fileSuccess', function (file, message) {
// Reflect that the file upload has completed
$('.resumable-file-' + file.uniqueIdentifier + ' .resumable-file-progress').html('(completed)');
});
r.on('fileError', function (file, message) {
// Reflect that the file upload has resulted in error
$('.resumable-file-' + file.uniqueIdentifier + ' .resumable-file-progress').html('(file could not be uploaded: ' + message + ')');
});
r.on('fileProgress', function (file) {
// Handle progress for both the file and the overall upload
$('.resumable-file-' + file.uniqueIdentifier + ' .resumable-file-progress').html(Math.floor(file.progress() * 100) + '%');
$('.progress-bar').css({width: Math.floor(r.progress() * 100) + '%'});
});
r.on('cancel', function () {
$('.resumable-file-progress').html('canceled');
});
r.on('uploadStart', function () {
// Show pause, hide resume
$('.resumable-progress .progress-resume-link').hide();
$('.resumable-progress .progress-pause-link').show();
});
}
</script>
route:
Route::post('uploadRadioChannelFile', 'UploadController#upload');
and controller:
class UploadController extends Controller
{
public function upload(Request $request)
{
try {
$receiver = new FileReceiver("file", $request, HandlerFactory::classFromRequest($request));
if ($receiver->isUploaded() === false) {
return response()->json([
"done" => '',
'status' => false
]);
}
$save = $receiver->receive();
if ($save->isFinished()) {
return $this->saveFile($save->getFile());
}
$handler = $save->handler();
return response()->json([
"done" => $handler->getPercentageDone(),
'status' => true
]);
} catch (UploadFailedException $e) {
}
}
protected function saveFile(UploadedFile $file)
{
$fileName = $this->createFilename($file);
//$mime = str_replace('/', '-', $file->getMimeType());
$dateFolder = Carbon::now()->year;
$public_html = config('app.public_path');
$filePath = "upload/{$dateFolder}/";
$file->move($public_html.$filePath, $fileName);
return response()->json([
'path' => $filePath,
'name' => $fileName,
'ffff' => $file->getClientOriginalName(),
]);
}
protected function createFilename(UploadedFile $file)
{
//$extension = $file->getClientOriginalExtension();
//$filename = str_replace("." . $extension, "", $file->getClientOriginalName()); // Filename without extension
//$filename .= "_" . md5(time()) . "." . $extension;
return time() . '.' . $file->getClientOriginalExtension();
}
}

VueJs Laravel Image Upload

Like the title says, I'm trying to do an image upload from VueJs to a Laravel endpoint. I discovered that the only way(if there is another please tell me) is to send the base64 of the image through the request. On the Vue side I think everything is covered.
However, on the Laravel side is where it gets complicated. I can't decode the base64 string that gets passed, and when I try to store the image in my AWS S3 bucket, it doesn't store properly. Here is the code:
VueJS
<template>
<input type="file" name="image" class="form-control" #change="imagePreview($event)">
</template>
methods: {
submitForm(){
axios.defaults.headers.post['Content-Type'] = 'multipart/form-data';
axios.post(this.$apiUrl + '/article', {
image: this.image
}).then(response => {
flash(response.data.message, 'success');
}).catch(e => {
console.log(e);
})
},
imagePreview(event) {
let input = event.target;
if (input.files && input.files[0]) {
var reader = new FileReader();
let vm = this;
reader.onload = e => {
this.previewImageUrl = e.target.result;
vm.image = e.target.result;
}
reader.readAsDataURL(input.files[0]);
}
}
}
Laravel:
$this->validate($request, [
'image' => 'required',
]);
// return response()->json(base64_decode($request->image));
$timestampName = microtime(true) . '.jpg';
$url = env('AWS_URL') . '/article_images/' .$timestampName;
Storage::disk('s3')->put($timestampName, base64_decode($request->image));
If I add the image validation rule, it says it's not an image..
I would also like to retrieve the extension if possible.
you can do it using FormData in JS part and use getClientOriginalExtension() on the file to get the extension in Laravel.
VueJS
imagePreview(event) {
let selectedFile = event.target.files[0];
vm.image = selectedFile;
}
submitForm(){
let fomrData = new FormData();
formData.append('image', vm.image);
axios.post(this.$apiUrl + '/article', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
})
.then(response => {
flash(response.data.message, 'success');
})
.catch(e => {
console.log(e);
});
}
Laravel
$this->validate($request, [
'image' => 'required',
]);
$image = $request->file('image');
$extension = $image->getClientOriginalExtension(); // Get the extension
$timestampName = microtime(true) . '.' . $extension;
$url = env('AWS_URL') . '/article_images/' .$timestampName;
Storage::disk('s3')->put($url, file_get_contents($image));
Here is a link that might be useful
Hope that it helps.

how to delete image from folder using dropzone?

I am using laravel framework 5.2. I have successfully implemented dropzone and i have also done with upload images. Now problem is that when i want to delete the image from folder it gives me error. I think my code is not right for deleting image.
Here is my add Upload image Function i have uploaded images in session:-
public function addContributorimages(Request $request){
if($request->ajax()){
$image=$_FILES['file'];
if(!empty($image)){
if($image['error']==0){
$name = pathinfo($_FILES['file']['name']);
$ext = $name['extension'];
$rand=str_random(24).'.'.$ext;
$destination = base_path() . '/public/images/ContributorImages/';
if(is_uploaded_file($image['tmp_name'])){
list( $width, $height, $source_type ) = getimagesize($image['tmp_name']);
if ($width >= 10 && $height >= 10){
move_uploaded_file($image['tmp_name'],$destination.$rand);
$request->session()->put('contributorimage.'.str_random(5).'.image',$rand);
$images = $request->session()->get('contributorimage');
echo "<pre>"; print_r($images);
}
else{
echo "Error";die;
}
}
}
}
}
}
This is my add Function of images
Here is my dropzone code :-
Dropzone.autoDiscover = false;
var fileList = new Array;
var i =0;
$("#my-awesome-dropzone").dropzone({
method:'POST',
maxFiles: 10,
paramName: "file",
maxFilesize: 10,
addRemoveLinks: true,
acceptedFiles: ".jpeg,.jpg,.png,.gif",
clickable: true,
init: function() {
// Hack: Add the dropzone class to the element
$(this.element).addClass("dropzone");
this.on("sending",function(file, xhr, formData) {
formData.append("_token", "{{ csrf_token() }}");
});
this.on("success", function(file, serverFileName) {
fileList[i] = {"serverFileName" : serverFileName, "fileName" : file.name,"fileId" : i };
//console.log(fileList);
i++;
});
this.on("removedfile", function(file) {
var rmvFile = "";
for(f=0;f<fileList.length;f++){
if(fileList[f].fileName == file.name)
{
rmvFile = fileList[f].serverFileName;
if (rmvFile){
$.ajax({
type: 'POST',
url: '../contributor/delete-subimages/'+rmvFile,
});
}
}
}
});
},
url: '../contributor/add-subimages',
});
});
My images are successfully uploaded but i want to remove the image from session as well as from folder can anyone help me how to do that
Here is my delete function of image:-
public function deleteContributorImage(Request $request,$name = null){
$imageName=explode('.',$name);
$imageRandomName = $request->session()->get('contributorimage.'.$imageName[0].'.image');
$destination = base_path() . '/public/images/ContributorImages/';
if(unlink($destination.$imageRandomName)){
$request->session()->forget('contributorimage.'.$imageName[0]);
echo "success";
}
else{
echo "failed";
}
}
Now when i upload images it create this sesssion now i am having two images in session
Array
(
[Dkf08] => Array
(
[image] => whywu3dprVPKKkhUgdIMAdLQ.jpg
)
[rH5NV] => Array
(
[image] => i2sZEqjMdiQHcKRyy5Km9vlu.jpg
)
)
can anyone hlep me how to slove this issue . Thanks in advance :)
you have to create one hidden filed for that and when you remove file from dropzone than that file name should be save in that hidden filed.
myDropzone.on('removedfile', function (file) {
var hidden_filed= document.getElementById('hidden_filed').value;
if (alreadyRemove == "") {
$('#deleteImage').val(file.name);
} else {
$('#deleteImage').val(hidden_filed+ ',' + file.name);
}
});
after that get that field as POST data in controller. From file name you can delete Image as usual.

Categories