laravel download file with ajax request - javascript

I am trying to download the file by sending required parameters via ajax request.
I first stored the output file to public/exports directory and on success callback tried to redirect to that file path.
public function downloadResults() {
/* get filter control inputs */
$inputParams = $this->request->input();
.
.
.
try {
$exportArr = $this->product->downloadResults($filterArr); <-- this will store the file to public directory.
} catch (\Exception $e) {
$jsonArr['success'] = false;
$jsonArr['message'] = $e->getMessage();
echo json_encode($jsonArr);
}
$jsonArr['success'] = true;
$jsonArr['filename'] = $exportArr['file'];
echo json_encode($jsonArr);
}
On callback,
$.ajax({
data: filter_rules,
url: "{{ #url("/dmf/download-results") }}",
type: 'POST',
dataType: 'json',
success: function(resp) {
$("#overlay").hide();
window.location.href = "{{ asset('public/exports/') }}" + '/' + resp.filename;
},
});
}
It then redirects to http://localhost:8000/public/exports/result_set_download_1589388303.xls route which doesn't exist.
So how can I access that file now?

check out this package downloadjs
you can use Fetch API to get the BLOB data from the server and download the blob using downloadjs

Related

AWS PDF file show in bootstrep model in Laravel

I have downloaded aws url like
https://xxx-xx-dev.s3.ap-south-1.amazonaws.com/std_check/6557122022151745398XtquBSY.pdf
When this url is put in ifrem the file is automatically downlaod instead of views in bootstrap model.
My code is Here,
View File is
function PDFOPEN(path) {
$.ajax({
type: 'post',
url: '{{ route('background.pdf.show') }}',
data: {
"_token": "{{ csrf_token() }}",
'path':path
},
success: function(data) {
if (data.status == true) {
} else {
toastr.error(data.message);
}
}
});
}
Controller File is
public function BackgroundVerifyShow(Request $request)
{
$file = \Storage::disk('s3')->url($request->path);
header('Content-Type: application/pdf');
header(sprintf("Content-disposition: inline;filename=%s", basename($file)));
#readfile($file);
}
So, How can read this file in ajax succss after bootsrep model
readfile function will return true or false.
public function BackgroundVerifyShow(Request $request)
{
$file = \Storage::disk('s3')->url($request->path);
header('Content-Type: application/pdf');
header(sprintf("Content-disposition: inline;filename=%s", basename($file)));
header("Content-Type: " . $asset->mime);
echo json_encode({status => readfile($file)});
}

if else statement in AJAX success

This is how i am trying to check json data. If the data inserts correctly i want the mentioned jquery in success code. But if it is not inserted then i want else code to run. But the if else conditions are not working properly.I am including php code and ajax code which i have tried. Am i doing it right?
AJAX
$( "#frm_add" ).on('submit',(function(e) {
e.preventDefault();
var img= new FormData(this);
datas = $("#frm_add").serializeArray();
$.each(datas,function(key,input){
img.append(input.name,input.value);
});
$.ajax({
url: "response_categories.php", // Url to which the request is send
type: "POST", // Type of request to be send, called as method
//data:new FormData(this),
data:img,
// data: {img:img,datas:datas}, // Data sent to server, a set of key/value pairs (i.e. form fields and values)
contentType: false, // The content type used when sending data to the server.
cache: false, // To unable request pages to be cached
processData: false, // To send DOMDocument or non processed data file it is set to false
success: function (data) // A function to be called if request succeeds
{
if(data == true)
{
$('#add_model').modal('hide');
$("#categories_grid").bootgrid('reload');
}
else
{
$("#nameerr").html("<p id='error' style='color:red'>"+data+"</p>");
}
}
});
}));
php
function insertCategories($params)
{
$fileName = $_FILES['cat_image']['name'];
$name = $params['cat_name'];
$type = $params['cat_type'];
$switch = $params['cat_switch'];
$chk=mysqli_query($this->conn,"select * from categories where cat_name='$name'");
if(mysqli_num_rows($chk)==0)
{
$sql = "INSERT INTO `categories` (cat_name,cat_image, cat_type, cat_switch) VALUES('$name','$fileName', '$type','$switch'); ";
echo $result = mysqli_query($this->conn, $sql) or die("error to insert Categories data");
if ($result) {
if (file_exists("images/" . $_FILES["cat_image"]["name"])) {
echo $fileName . " <span id='invalid'><b>already exists.</b></span> ";
} else {
$sourcePath = $_FILES['cat_image']['tmp_name']; // Storing source path of the file in a variable
$targetPath = "images/" .$fileName; // Target path where file is to be stored
move_uploaded_file($sourcePath, $targetPath); // Moving Uploaded file
}
}
echo json_encode($result);
}
}
Add the error command in your ajax call to execute if the command fails or returns no data in general
$.ajax({
url: "response_categories.php", // Url to which the request is send
type: "POST", // Type of request to be send, called as method
data:img,
contentType: false, // The content type used when sending data to the server.
cache: false, // To unable request pages to be cached
processData: false, // To send DOMDocument or non processed data file it is set to false
success: function (data), // A function to be called if request succeeds
{
if(data)
{
$('#add_model').modal('hide');
$("#categories_grid").bootgrid('reload');
}
else
{
$("#nameerr").html("<p id='error' style='color:red'>"+data+"</p>");
}
}
error: function (data)
{
$("#namerr".html("<p id='error' style='color:red'>"+data+"</p>");
}
});
I think You have problem with response convention: Sometimes You call die() method (PHP: 12 line), sometimes You call json_endcode() (PHP: 25 line), sometimes echo with plain string.
In this type of actions You should:
Always output JSON from backend script. Mixing response types is really pain in the ass, it's hard to parse and test.
Use response object with uniform structure - that might help with building complex applications and easy to modify
Example pseudocode:
PHP
if($success) {
die(json_encode([
'error' => false,
'message' => 'Thank You',
'data' => $some_extra_data
]));
} else {
die(json_encode([
'error' => true,
'message' => 'Sorry',
'data' => $some_extra_data
]));
}
Then in ajax.success() method, its really easy to handle:
success: function (data) {
try {
var response = JSON.parse(data)
if(response.error == true) {
$('#nameerr').text(response.message)
} else {
$('#add_model').modal('hide');
$("#categories_grid").bootgrid('reload');
}
} catch (err) {
alert('Sorry. Server response is malformed.')
}
}

Sending PDF file to server (PHP LARAVEL) using AJAX

I am trying to upload a file (PDF) by AJAX to my server to be handled by a php script in a laravel project. I cannot get the file to send and be received on the server.
In the network I can see that the POST request is getting a 200 response, however it is returning a response of 'file not present', which is the response from laravel.
Also in the post request the Request Payload contains the following
------WebKitFormBoundaryliAmA3wxs0bB32iZ--
Please see the js and html and php below:
html
<form enctype="multipart/form-data">
<input type="file" id="cv" name="cv"/>
<button id="file-send">Add</button>
</form>
js
$('#file-send').bind('click', function () {
$.ajax({
url:"test",
data: new FormData($("#cv")[0]),
type:'POST',
processData: false,
contentType: false,
success:function(response){
console.log(response);
},
});
});
LARAVEL CODE
public static function uploadingFile(){
if (Input::hasFile('cv'))
{
return "file present";
}
else{
return "file not present";
}
Try this:
JS:
$('#file-send').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 */
});
Php:
<?php
if ( $_FILES['file']['error'] > 0 ){
echo 'Error: ' . $_FILES['file']['error'] . '<br>';
}
else {
if(move_uploaded_file($_FILES['file']['tmp_name'], 'uploads/' . $_FILES['file']['name']))
{
echo "File Uploaded Successfully";
}
}
?>
Try This Plugin to upload file
http://malsup.com/jquery/form/#file-upload
var options = {
beforeSubmit: showRequest,
success: showResponse,
dataType :'json'
};
$('#file-send').ajaxSubmit(options);
function showRequest()
{
//before uploading file
}
function showResponse()
{
//response after uploading file
}

Correct way to pass data to Jquery Ajax

Whats the correct way to pass data to ajax using jquery. I have the following method and I want to pass the CSRF token from a meta tag but it doesn't work.
<meta name="csrf-token" content="{{ csrf_token() }}">
<div class="fallback">
<input type="file" name="logo" id="logo" class="inputfile"/>
</div>
$(document).on("change", ".fallback .inputfile", function() {
$.ajax({
url: "/upload",
type: 'POST',
cache: false,
data: {
_token: $('meta[name="csrf-token"]').attr('content')
},
files: $(":file", this),
iframe: true,
processData: false
}).complete(function(data) {
console.log(data);
// $('#img-thumb').attr('src', data.path);
// $('input[name="job_logo"]').val(data.path);
});
});
Laravel method to process the file:
public function upload(Request $request) {
if($request->hasFile('logo')) {
//upload an image to the /img/tmp directory and return the filepath.
$file = $request->file('logo');
$tmpFileName = time() . '-' . $file->getClientOriginalName();
$tmpFilePath = '/img/tmp/';
$file = $file->move(public_path() . $tmpFilePath, $tmpFileName);
$path = $tmpFilePath . $tmpFileName;
return response()->json(['path'=> $path], 200);
} else {
return response()->json(false, 200);
}
}
I've followed the documentation from the following source https://cmlenz.github.io/jquery-iframe-transport/
I get tokenmismatch error. Note this is using Laravel 5.1
* UPDATE *
Should be able to add the token directly to data attribute as the csrf token is already in my meta tag. Below is an example done using backbone.js/ruby on rails, but I'm not an expert on backbone/rails so if any one can translate that into jquery it would be helpful. (http://estebanpastorino.com/2013/09/27/simple-file-uploads-with-backbone-dot-js/)
uploadFile: function(event) {
var values = {};
var csrf_param = $('meta[name=csrf-param]').attr('content');
var csrf_token = $('meta[name=csrf-token]').attr('content');
var values_with_csrf;
if(event){ event.preventDefault(); }
_.each(this.$('form').serializeArray(), function(input){
values[ input.name ] = input.value;
})
values_with_csrf = _.extend({}, values)
values_with_csrf[csrf_param] = csrf_token
this.model.save(values, { iframe: true,
files: this.$('form :file'),
data: values_with_csrf });
}
processData: false
You've told jQuery to not convert the object containing your data into a format suitable for transmitting over HTTP.
You need to add this to your page:
$(function() {
$.ajaxSetup({ headers: { 'X-CSRF-TOKEN' : '{{ csrf_token() }}' } });
});
This is because the AJAX needs the X-CSRF-TOKEN everytime you send an AJAX request to the server (unless you turn it off, which I don't recommend).
SOURCE: my own experiences with Laravel.

Not able to get file copying progress

Am trying to get progress of file being copied
initially i send a request to copy the file using the below code. once the file is created. i send a response success=1 and start the copying process and also call getProgress
$.ajax({
url:'copyFile.php',
type: 'post',
dataType: 'json',
data: {'data':someData},
success: function(data) {
if(data.success){
progressIndex=setInterval(getProgress, 1000 );
}
},
error:function(err){
console.log(err);
}
});
function getProgress(){
$.ajax({
url:'FileUploadProgress.php',
type: 'post',
dataType: 'json',
data: {'progress':'1'},
success: function(data) {
if(!data.success){
clearTimeout(progressIndex);
}
},
error:function(err){
console.log(err);
}
});
}
FileUploadProgress.php
class FileUploadProgress{
private $filename;
private $progress;
public function setfileProgress($filename,$progress){
$this->filename=$filename;
$this->progress=$progress;
}
function returnProgress(){
if(empty($this->filename) || empty($this->progress)){
echo json_encode(array('success'=>'0'));
}else{
echo json_encode(array('success'=>1,'filename'=>$this->filename,'progress'=>$this-
>progress));
}
}
}
$fileuploadprogress=new FileUploadProgress;
if($_POST['progress']){
$fileuploadprogress->returnProgress();
}
while copying am getting the progress and calling the function setfileProgress
to set the progress. Also in client side i have requested for progress , but wat am getting is success=0 and $this->progress is empty
Am i missing anything in my code. Please let me know
You have to make way to query some datasource to get your progress status.
Like dumping progress status in some DB table or file, etc..
However PHP have some hacks, that works in some enviroment.
Check following docs: Session Upload Progress.

Categories