how to create window.location response in ajax - javascript

For creating a .zip file for checked items with selectbox, i need a response back from the php that leads to the path the .zip file is stored.
This is my ajax call:
// AJAX for Checkbox download
$(document).on('click' , '.cb_down' , function() {
var checkboxes_down = [];
$('.rafcheckbox').each(function() {
if(this.checked) {
checkboxes_down.push($(this).val());
}
});
checkboxes_down = checkboxes_down.toString();
$.ajax({
url:"",
method:"POST",
data:{ checkboxes_down:checkboxes_down },
success:function(response){
window.location = response; // this should lead me to the zip file
}
//.........
My php:
// Multiple download (checkboxes)
if(isset($_POST["checkboxes_down"])) {
// create a tmp folder for the zip file
$tmpfolder = $MainFolderName.'/tmpzip';
if (!is_dir($tmpfolder)) {
mkdir($tmpfolder, 0755, true);
}
$checkboxfiles = explode("," , $_POST["checkboxes_down"]);
$filename = "archive.zip";
$filepath = $tmpfolder."/";
foreach($checkboxfiles as $checkboxfile) {
Zip($checkboxfile, $tmpfolder."/archive.zip"); // Zip is a function that creates the .zip file
}
// header come here
echo $filepath . $filename; // the path to the .zip file
exit;
The .zip file is successful created. I checked it.
The problem is: i do not get the response back from the php script.
So i can not download the .zip file.
What i am doing wrong?
! I changed the echo to 'zip file is created' but even that echo i do not receive as response back

Related

Returning value to Javascript from PHP called from XMLHttpRequest

I am attempting to add an "Upload Image" feature to my AjaxChat window. The upload to the server works great, but now I need to be able to return the tmp_name/location of the file that was uploaded. In my Javascript I have the following (main) code (some setup code has been omitted because it is unnecessary -- The upload works as expected):
// Set up request
var xhr = new XMLHttpRequest();
// Open connection
xhr.open('POST', 'sites/all/modules/ajaxchat/upload.php', true);
// Set up handler for when request finishes
xhr.onload = function () {
if (xhr.status === 200) {
//File(s) uploaded
uploadButton.innerHTML = 'Upload';
} else {
alert('An error occurred!');
}
};
// Send data
xhr.send(formData);
My PHP code ("upload.php") is as follows:
<?php
$valid_file = true;
echo '<script type="text/javascript">alert("PHP Code Reached");</script>';
if($_FILES['photo']['name']) {
//if no errors...
if(!$_FILES['photo']['error']) {
//now is the time to modify the future file name and validate the file
$new_file_name = strtolower($_FILES['photo']['tmp_name']); //rename file
if($_FILES['photo']['size'] > (1024000)) { //can't be larger than 1 MB
$valid_file = false;
$message = 'Oops! Your file\'s size is to large.';
exit("$message");
}
//if the file has passed the test
if($valid_file) {
//move it to where we want it to be
move_uploaded_file($_FILES['photo']['tmp_name'], '/var/www/html/images'.$new_file_name);
$message = 'Congratulations! Your file was accepted.';
exit("$message");
}
}
//if there is an error...
else {
//set that to be the returned message
$message = 'Ooops! Your upload triggered the following error: '.$_FILES['photo']['error'];
exit("$message");
}
}
?>
I can tell my PHP code is being run because the image uploads to the server. However, I read that I could generate a Javascript "alert" popup from within the PHP using the following code:
echo '<script type="text/javascript">alert("PHP Code Reached");</script>';
But the above line does not seem to be doing anything. Is this expected since I'm using an XMLHttpRequest, rather than running the PHP directly?
Ultimately my goal is to pass the name of the uploaded file back to the Javascript that called the PHP so that I can create the image url, put it in img tags, and send it to the chat window using ajaxChat.insertText() and ajaxChat.sendMessage(). I'm not sure if this is possible the way I'm running my PHP, though. How would one go about doing this?
When you use XMLHttpRequest, the output of the server script is in the responseText of the object. So you can do:
xhr.onload = function () {
if (xhr.status === 200) {
//File(s) uploaded
uploadButton.innerHTML = xhr.responseText;
} else {
alert('An error occurred!');
}
};
If you want to send back multiple pieces of information, such as an informative message and the name of the file, you can use JSON to encode an associative array, which will become a Javascript object when you parse it.

Uploading Zip File To Server With AJAX

I have a php file which takes a zip file and unpacks it then places it at the desired path on my server.
It works great with a typical form that calls on the php file in the action. I am trying to make this work with AJAX but I have tried every piece of code I can find without any luck.
Is there something here I am missing? Surely this can be done?
Form for uploading the zip file,
<div id="response"></div>
<form enctype="multipart/form-data" method="post" action="">
<label>Choose a zip file to upload: <input type="file" name="zip_file" id="zip_file" /></label>
<br />
<input type="submit" name="submit" value="Upload" onClick="uploadZip()" />
</form>
Current JS - I get no errors, the page actually reloads with my current script..
<script>
function uploadZip() {
formdata = new FormData();
if (formdata) {
$('.main-content').html('<img src="LoaderIcon.gif" />');
$.ajax({
url: "assets/upload-plugin.php",
type: "POST",
data: formdata,
processData: false,
contentType: false,
success: function (res){
document.getElementById("response").innerHTML = res;
}
});
}
}
</script>
php script which handles uploading the zip and unzipping it before placing it on the server.
function rmdir_recursive($dir) {
foreach(scandir($dir) as $file) {
if ('.' === $file || '..' === $file) continue;
if (is_dir("$dir/$file")) rmdir_recursive("$dir/$file");
else unlink("$dir/$file");
}
rmdir($dir);
}
if($_FILES["zip_file"]["name"]) {
$filename = $_FILES["zip_file"]["name"];
$source = $_FILES["zip_file"]["tmp_name"];
$type = $_FILES["zip_file"]["type"];
$name = explode(".", $filename);
$accepted_types = array('application/zip', 'application/x-zip-compressed', 'multipart/x-zip', 'application/x-compressed');
foreach($accepted_types as $mime_type) {
if($mime_type == $type) {
$okay = true;
break;
}
}
$continue = strtolower($name[1]) == 'zip' ? true : false;
if(!$continue) {
$message = "The file you are trying to upload is not a .zip file. Please try again.";
}
/* PHP current path */
$path = '../plugins/'; // absolute path to the directory where zipper.php is in
$filenoext = basename ($filename, '.zip'); // absolute path to the directory where zipper.php is in (lowercase)
$filenoext = basename ($filenoext, '.ZIP'); // absolute path to the directory where zipper.php is in (when uppercase)
$targetdir = $path . $filenoext; // target directory
$targetzip = $path . $filename; // target zip file
/* create directory if not exists', otherwise overwrite */
/* target directory is same as filename without extension */
if (is_dir($targetdir)) rmdir_recursive ( $targetdir);
mkdir($targetdir, 0777);
/* here it is really happening */
if(move_uploaded_file($source, $targetzip)) {
$zip = new ZipArchive();
$x = $zip->open($targetzip); // open the zip file to extract
if ($x === true) {
$zip->extractTo($targetdir); // place in the directory with same name
$zip->close();
unlink($targetzip);
}
$message = "Your .zip file was uploaded and unpacked.";
} else {
$message = "There was a problem with the upload. Please try again.";
}
}
This php function works great as long as I do this with the form action. So I am sure my problem exist in the AJAX function.
Thanks for any help you can provide.
formdata = new FormData();
You've created a FormData object but you never put any data into it.
The easiest approach is to specify the form:
formdata = new FormData(document.forms[0]);
You also need to stop the submit button from actually submitting the form so that the JS can do something.
A cleaner approach would be to:
Stop using intrinsic event attributes
Use the submit handler for the form
Get the form from the event
<input type="submit" name="submit" value="Upload" onClick="uploadZip()" />
Becomes:
<input type="submit" name="submit" value="Upload">
function uploadZip() {
formdata = new FormData();
becomes:
function uploadZip(event) {
var formdata = new FormData(this);
// Rest of function
event.preventDefault();
}
and you add:
jQuery("form").on("submit", uploadZip);

Downloading ajax response which is encoded [duplicate]

I have a button and onclick it will call an ajax function.
Here is my ajax function
function csv(){
ajaxRequest = ajax();//ajax() is function that has all the XML HTTP Requests
postdata = "data=" + document.getElementById("id").value;
ajaxRequest.onreadystatechange = function(){
var ajaxDisplay = document.getElementById('ajaxDiv');
if(ajaxRequest.readyState == 4 && ajaxRequest.status==200){
ajaxDisplay.innerHTML = ajaxRequest.responseText;
}
}
ajaxRequest.open("POST","csv.php",false);
ajaxRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
ajaxRequest.send(postdata);
}
I create the csv file based on the user input. After it's created I want it to prompt download or force download(preferably force). I am using the following script at the end of the php file to download the file. If I run this script in a separate file it works fine.
$fileName = 'file.csv';
$downloadFileName = 'newfile.csv';
if (file_exists($fileName)) {
header('Content-Description: File Transfer');
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename='.$downloadFileName);
ob_clean();
flush();
readfile($fileName);
exit;
}
echo "done";
But If I run it at the end of csv.php it outputs the contents of the file.csv into the page(into the ajaxDiv) instead of downloading.
Is there a way to force download the file at the end of csv.php?
AJAX isn't for downloading files. Pop up a new window with the download link as its address, or do document.location = ....
A very simple solution using jQuery:
on the client side:
$('.act_download_statement').click(function(e){
e.preventDefault();
form = $('#my_form');
form.submit();
});
and on the server side, make sure you send back the correct Content-Type header, so the browser will know its an attachment and the download will begin.
#joe : Many thanks, this was a good heads up!
I had a slightly harder problem:
1. sending an AJAX request with POST data, for the server to produce a ZIP file
2. getting a response back
3. download the ZIP file
So that's how I did it (using JQuery to handle the AJAX request):
Initial post request:
var parameters = {
pid : "mypid",
"files[]": ["file1.jpg","file2.jpg","file3.jpg"]
}
var options = {
url: "request/url",//replace with your request url
type: "POST",//replace with your request type
data: parameters,//see above
context: document.body,//replace with your contex
success: function(data){
if (data) {
if (data.path) {
//Create an hidden iframe, with the 'src' attribute set to the created ZIP file.
var dlif = $('<iframe/>',{'src':data.path}).hide();
//Append the iFrame to the context
this.append(dlif);
} else if (data.error) {
alert(data.error);
} else {
alert('Something went wrong');
}
}
}
};
$.ajax(options);
The "request/url" handles the zip creation (off topic, so I wont post the full code) and returns the following JSON object. Something like:
//Code to create the zip file
//......
//Id of the file
$zipid = "myzipfile.zip"
//Download Link - it can be prettier
$dlink = 'http://'.$_SERVER["SERVER_NAME"].'/request/download&file='.$zipid;
//JSON response to be handled on the client side
$result = '{"success":1,"path":"'.$dlink.'","error":null}';
header('Content-type: application/json;');
echo $result;
The "request/download" can perform some security checks, if needed, and generate the file transfer:
$fn = $_GET['file'];
if ($fn) {
//Perform security checks
//.....check user session/role/whatever
$result = $_SERVER['DOCUMENT_ROOT'].'/path/to/file/'.$fn;
if (file_exists($result)) {
header('Content-Description: File Transfer');
header('Content-Type: application/force-download');
header('Content-Disposition: attachment; filename='.basename($result));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($result));
ob_clean();
flush();
readfile($result);
#unlink($result);
}
}
I have accomplished this with a hidden iframe. I use perl, not php, so will just give concept, not code solution.
Client sends Ajax request to server, causing the file content to be generated. This is saved as a temp file on the server, and the filename is returned to the client.
Client (javascript) receives filename, and sets the iframe src to some url that will deliver the file, like:
$('iframe_dl').src="/app?download=1&filename=" + the_filename
Server slurps the file, unlinks it, and sends the stream to the client, with these headers:
Content-Type:'application/force-download'
Content-Disposition:'attachment; filename=the_filename'
Works like a charm.
You can't download the file directly via ajax.
You can put a link on the page with the URL to your file (returned from the ajax call) or another way is to use a hidden iframe and set the URL of the source of that iframe dynamically. This way you can download the file without refreshing the page.
Here is the code
$.ajax({
url : "yourURL.php",
type : "GET",
success : function(data) {
$("#iframeID").attr('src', 'downloadFileURL');
}
});
You can do it this way:
On your PHP REST api: (Backend)
header('Content-Description:File Transfer');
header('Content-Type:application/octet-stream');
header('Content-Disposition:attachment; filename=' . $toBeDownloaded);
header('Content-Transfer-Encoding:binary');
header('Expires:0');
header('Cache-Control:must-revalidate');
header('Pragma:public');
header('Content-Length:'.filesize($toBeDownloaded));
readfile($toBeDownloaded);
exit;
On your javascript code: (FRONTEND)
const REQUEST = `API_PATH`;
try {
const response = await fetch(REQUEST, {
method: 'GET',
})
const fileUploaded = await response.blob();
const url = window.URL.createObjectURL(fileUploaded);
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'YOUR_FILE_NAME_WITH_EXTENSION');
document.body.appendChild(link);
link.click();
} catch (error) {
console.log(error)
}

Froala - image upload JSON response

I am using Froala editor for my website. This editor have built in image upload function - image upload is working fine, but I am having trouble with response.
This is from the documentation:
The server processes the HTTP request.
The server has to process the upload request, save the image and return a hashmap containing a link to the uploaded image. The returned hashmap needs to look like: { link: 'path_to_uploaded_file/file.png' }
This is my function for returning link:
public function froala_upload()
{
header('Content-type: application/json');
$folder = 'public/img/media';
$slika = $this->site->single_upload($folder, 'jpg|jpeg|png|bmp|JPG|JPEG|PNG|BMP');
$link = array("link" => $slika);
echo json_encode($link);
}
This is JS code:
$('textarea').editable({
inlineMode: false,
imageUploadParam: "userfile",
imageUploadURL: "<?php echo base_url() ?>admin/froala_upload",
// Set the image error callback.
imageErrorCallback: function (data) {
// Bad link.
if (data.errorCode == 1) {
console.log(data);
}
// No link in upload response.
else if (data.errorCode == 2) {
console.log(data);
}
// Error during file upload.
else if (data.errorCode == 3) {
console.log(data);
}
}
});
When I upload image I get following error:
Object { errorCode=1, errorStatus="Bad link."}
And this is response that I get:
{"link":"7d59d61.jpg"}
What seem to be a problem?
Froala image upload documentation
You must return the absolute image path :
$link = array("link" => '/img/media/'.$slika);
Because Froala looks for it to http://example.com/7d59d61.jpg
The problem is that the image cannot be loaded from the returned link. You'd have to make sure that the image can be accessed from it. Froala Editor uses the link you return for src attribute from img tag. I think you'd have to do something like:
$link = array("link" => $slika . 'public/img/media');

No way to pass data using form with Uploadify

sorry if I am being redundant but I've tried every single example I found here and on google :D
What I am trying to do is on the upload of image, what was typed on inputbox will be send along to the uplodify.php where my insert is. My problem is, name of picture has being saved to the mysql but what was typed on the textfield dont.
Would you guys let me know what is going on?
This is the part of my code
'multi' : true,
'auto' : false,
'onUploadStart' : function(file) {
$("#file_upload").uploadify('settings', 'formData', {'galeria': $('#galeria').val()});
},
<form id="form1" name="form1" action="">
<p>
<input type="file" id="file_upload" name="file_upload" />
<br>
<br>
Galeria<br>
<label>
<input type="text" name="galeria" id="galeria">
uplodify.php
$galeria = $_POST['galeria'];
$regiao = $_POST['regiao'];
if (!empty($_FILES)) {
$img = $_FILES['Filedata']['name'];
$ext = substr($img, -4);
$img = md5($img).date("dmYHis").$ext;
$tempFile = $_FILES['Filedata']['tmp_name'];
$targetPath = $_SERVER['DOCUMENT_ROOT'] . $_REQUEST['folder'] . '/';
$targetFile = str_replace('//','/',$targetPath) . $img;
$adicionar = mysql_query ("INSERT INTO imagens (foto, galeria, regiao) VALUES('$img','$galeria','$regiao')");
// $fileTypes = str_replace('*.','',$_REQUEST['fileext']);
// $fileTypes = str_replace(';','|',$fileTypes);
// $typesArray = split('\|',$fileTypes);
// $fileParts = pathinfo($_FILES['Filedata']['name']);
// if (in_array($fileParts['extension'],$typesArray)) {
// Uncomment the following line if you want to make the directory if it doesn't exist
// mkdir(str_replace('//','/',$targetPath), 0755, true);
move_uploaded_file($tempFile,$targetFile);
echo str_replace($_SERVER['DOCUMENT_ROOT'],'',$targetFile);
// } else {
// echo 'Invalid file type.';
// }
}
Try changing your onUploadStart method to extend the uploadify formData property like this:
onUploadStart: function ( file ) {
var $fileUpload = $('#file_upload')
, formData = $fileUpload.uploadify('settings', 'formData')
, newFormData = $.extend({}, formData, { galeria: $('#galeria').val() });
$fileUpload.uploadify('settings', 'formData', newFormData);
}
I finally managed to made it work
This is the code I used
$('#file_upload').attr('file_upload', response).show();
$.post("insert2.php",{name: fileObj.name, galeria: $("#galeria").val(), regiao: $("#regiao").val()}, function(info) {
alert(info); // alert UPLOADED FILE NAME
});
}
});
Now I have a different problem lol it always show right...
Since the code to save the file on dabase is on insert2.php and the code to rename the picture inside the uploadify.php. How can I save the new name on the database instead the name of file I uploaded?
Another question.... is that a way to generate a thumbnail based on those pictures on database?

Categories