Why my ajax request always throws error? - javascript

Here is my code:
PHP:
public function export(Request $request){
$file = "export.txt";
if(isset($_POST["type"])){
file_put_contents("$file",$_POST["text"]);
}
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: text/plain'); // the appropriate header type for txt file
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
readfile($file);
exit;
}
}
JS:
$(document).on('click', '#export', function () {
var names = ['علی','فرید'];
var namess = names.join('\n');
$.ajax({
type: "post",
url: "/export",
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
data: {
type: "save",
text: namess
},
dataType: "json",
success: function(){
var href = '/export?filename=export.txt';
window.location = href;
},
error: function(){
alert('wrong');
}
});
})
Always error part executes. I mean it always alert wrong. How can I fix it? All I'm trying to do it making a .txt download file.
Noted that when I run this path: http://localhost:8000/export?filename=export.txt .. then export.txt will be downloaded.

You can download using this code:
window.location="export?filename=export.txt";
If you want to post data :
$('<form action="comments.php" method="POST"/>')
.append($('<input type="hidden" name="type" value="save">'))
.append($('<input type="hidden" name="text" value="'+ namess +'">'))
.appendTo($(document.body)) //it has to be added somewhere into the <body>
.submit();
Full code:
$(document).on('click', '#export', function () {
var names = ['علی','فرید'];
var namess = names.join('\n');
$('<form action="export?filename=export.txt" method="POST"/>')
.append($('<input type="hidden" name="type" value="save">'))
.append($('<input type="hidden" name="text" value="'+ namess +'">'))
.appendTo($(document.body)) //it has to be added somewhere into the <body>
.submit();
});
});

Basically Ajax is not usually used for file download however you can tune to make it feel and that is what you have done the only thing is when the request is successful us a "document.location" function from javascript to popup a new window for downloading a file. Besides for the error you are getting, try debugging your PHP code by playing around with your PHP header by starting with most important PHP Headers such as
header('Content-Type: text/plain');
header('Content-Disposition: attachment;filename="'.basename($file).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
ob_clean();
flush();
readfile($fileName);
exit;
check you code works with minimal information if it works then start adding more header one at a time, this helps in resolving problem with minimal information.
Hope this helps.

Related

Send textarea data to a file using JS & PHP and preserving line breaks

I have a form in which I have a textarea showing the result of reading a file (via PHP); I want it to edit and pressing a button, store it back
<?php
$salida = file_get_contents($path);
echo "<textarea rows='10' cols='100' id='file' name='file'>" . "$salida" . "</textarea>";
?>
Saving method (JS)
document.getElementById('btn-save').addEventListener('click', function(e) {
e.preventDefault();
request({
method: 'GET',
url: 'actions/save.php?file='+document.getElementById('file').value
}, function(ok) {
...
}, function(ko) {
...
});
});
save.php
<?php
$TEMP = '/tmp/file.tmp';
if (isset($_GET['file']))
{
$fh = fopen($TEMP, "w+");
$string = $_GET['file'];
fwrite($fh, $string); // Write information to the file
fclose($fh); // Close the file
}
The file is like:
line1=a
line2=b
line3=c
Problem is: when reading, it shows all the lines correctly; but when saving (methods above), the file appears like:
line1=aline2=bline3=c
What do I need to preserve the breaks in the file?
Thanks in advance
You could use the built in nl2br() function on the output of that file:
<?php
$salida = file_get_contents($path);
echo "<textarea rows='10' cols='100' id='file' name='file'>" . nl2br($salida) . "</textarea>";
?>
You should use POST method not GET. If your file will contain more then GET limit then you lost content.
document.getElementById('btn-save').addEventListener('click', function(e) {
e.preventDefault();
request({
method: 'POST',
url: 'actions/save.php',
data: {content: document.getElementById('file').value}
}, function(ok) {
...
}, function(ko) {
...
});
});
and PHP file
if (isset($_POST['content']))
{
$fh = fopen($TEMP, "w+");
$string = $_POST['content'];
fwrite($fh, $string); // Write information to the file
fclose($fh); // Close the file
}

Why JS opens a txt file instead of downloading it?

Here is my code:
Server Side:
public function export(){
$arr = array();
if($_POST["type"] == "save"){
$name = "export.txt";
file_put_contents("$name",$_POST["text"]);
$arr["type"] = "link";
$arr["url"] = "http://localhost:8000/{$name}";
}
return $arr;
}
Client Side:
$(document).on('click', '#export', function () {
var names = ["سعید خرمی", "فرید هادوی"];
var namess = names.join('\n');
$.ajax({
type: "post",
url: "/export",
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
data: {
type: "save",
text: namess
},
dataType: "json",
success: function(data){
var href = data.url;
window.location = href;
}
});
})
When I click on #export (button), it opens that .txt file (instead of downloading it). Something like this:
Noted that I use chrome .. Also it doesn't work in other browsers.
How can I force it to download that .txt file?
Change your success part like this,
success: function(data){
var href = download.php?filename=export.txt;
window.location = href;
}
And in your download.php:
Get the file name from the GET variable filename (say as $file).
Send the headers:
<?php
$file = $_GET['filename']; // get the filename
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: text/plain'); // the appropriate header type for txt file
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
readfile($file);
exit;
}
?>
Source: PHP Readfile Documentation

Save txt file from javascript with ajax call to PHP

Edit: I have a solution of sorts, but I do not understand why ajax is not working. Please see the edit below.
I want to save a txt file generated in javascript to the client machine.
I want the user to remain on the same webpage.
I am doing it via ajax with a call to a php page.
I want it to work in all major pc browsers; Chrome, Firefox, Internet Explorer and Edge.
Here is what I have so far:
htmlsave.js
dataARR = {
SaveFile: "This is the content.\nLine2.\nLine3"
};
var dataJSON = JSON.stringify(dataARR);
$.ajax({
type: "POST",
url: "htmlsave.php",
async: true,
cache: false,
crossDomain: false,
data: { myJson: dataJSON },
success: function (data) {
alert("success");
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert("failure");
}
});
htmlsave.php
<?php
if(!isset($_POST) || !isset($_POST['myJson'])) {
exit(0);
}
$data = json_decode($_POST['myJson'], true);
if(!array_key_exists('SaveFile', $data) || !isset($data['SaveFile'])){
exit(0);
}
$contents = strval($data['SaveFile']);
header("Pragma: public"); // required
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private", false); // required for certain browsers
header("Content-Type: text/plain");
header("Content-Disposition: attachment; filename=\"mysavefile.txt\";" );
header("Content-Transfer-Encoding: binary");
header("Content-Length: " . strlen($contents));
ob_clean();
flush();
echo $contents;
?>
What comes back (ie the data argument in success) is "This is the content.\nLine2.\nLine3".
There is no prompt to save the file with content "This is the content.\nLine2.\nLine3" as I had hoped.
Edit: A solution (but not a great one)
I have done a bit of tinkering and have something that works, in a fashion. Instead of calling through ajax I write in my javascript
document.location = "htmlsave.php?myJson=Line1Line2";
and in my php I have altered it to a get with
if(!isset($_GET) || !isset($_GET['myJson'])) {
exit(0);
}
$contents = $_GET['myJson'];
This works. This will be ok for small files, but I wanted to do reasonably large text files, and even zipped using lzw encoding. Anyone know why Ajax is not working?
Make sure your htmlsave.php starts with
<?php
If it does, see if your webserver is configured to pass .php files to your php implementation (fpm, mod_php, etc...)

Save file in local pc using PHP headers

I'm developing an SVG editor. I have to save the svg picture on the local disk. As you know, for safety reasons, it is impossible do it directly with javascript. So I decided to approach the problem with the server side help. I wrote the following PHP routine in a file called "savefile.php":
<?php
$mime = array('xls' => 'application/vnd.ms-excel', 'xml' => 'application/xml', 'html' => 'text/html', 'cvs' => 'text/plain', 'svg' => 'text/plain', 'txt' => 'text/plain', 'json' => 'text/plain', 'array' => 'text/plain');
if (isset($_POST['format']) && isset($_POST['filename']) && isset($_POST['content'])) {
$filename = $_POST['filename'];
$format = $_POST['format'];
$content = $_POST['content'];
$fullName = $filename . '.' . $format;
header('Pragma: public');
header("Content-Description: File Transfer");
header("Content-Transfer-Encoding: binary");
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header("Cache-Control: public");
header('Content-Type: ' . $mime[$format]);
header('Content-Disposition: attachment; filename="' . basename($fullName) . '"');
echo $content;
}
?>
On the server side I call, the PHP procedure, with this code:
var obj = {
format: 'svg',
filename: 'myfilename',
content: glb.Draw_active().GetDisegno().svg()
};
$.post("php/savefile.php",obj,function(data,status,xhr){console.log('Executed');});
When the software execute the above code, the browser should open the savefile window and wait the confirm from the user..... but nothing happens. I'm sure that the PHP routine is executed, it is also executed the callback routine, but nothing else.
Something is wrong, my suspect is on the javascript client-side code but I'm not able to find any documentation. May be someone have experience on this procedure?
Thanks a lot.
Thanks to #Quentin for the help I have solved the problem. The PHP code above is working, I had to change the Javascript part. Here the working code:
The SaveFile routine:
/*
#datatype : 'svg', 'xml', 'txt', 'xls', 'csv', 'html', etc see the list in PHP file
#filename : filename without extension
#exportServer : name of the PHP file on the server
#content : content of the file to save
*/
var saveFile = function(datatype, filename, exportServer,content){
var HInput = function(value, name, form) {
var I = document.createElement('input');
I.name = name;
I.value = value;
I.type = 'hidden';
form.appendChild(I);
},
HTextArea = function(value, name, form) {
var tA = document.createElement('textarea');
tA.name = name;
tA.value = value;
form.appendChild(tA);
};
var form = document.createElement('form');
HInput(filename, 'filename', form);
HInput(format, 'format', form);
HTextArea(content, 'content', form);
form.action = exportServer;
form.method = 'post';
document.body.appendChild(form);
form.submit();
document.body.removeChild(form);
}
.... for my need I call it in this way:
saveFile('svg','myfilename',"php/savefile.php",data);
thats all...... ;)

php How to Open Save As Dialog? Script Downloads Automatically

I have a download button that fires htmlcanvas and downloads html and saves it as a png file. I did not configure it as I don't understand javascript. I have played around with several tutorials for downloading files but I cannot get a dialog to open on click, regardless of which tutorial I have tried the image downloads to the download folder of whatever device the page is being viewed on. I think this is an issue with the javascript and not the php?
<script type="text/javascript">
var $loading = $('#loader').hide();
$('#carddownload').on('click', function() {
showimage();
});
$(document)
.ajaxStart(function () {
$loading.show();
})
.ajaxStop(function () {
$loading.hide();
});
function showimage(){
html2canvas([document.getElementById('card')], {
onrendered: function(canvas)
{
var img = canvas.toDataURL()
$.post("save.php", {data: img}, function (file) {
window.location.href ="downloadpng.php?path="+ file});
}
});
}
</script>
<?php
$file = trim($_GET['path']);
// force user to download the image
if (file_exists($file)) {
header('Content-Type: application/download');
header('Content-Description: File Transfer');
header('Content-Type: image/png');
header('Content-Disposition: attachment; filename='.basename($file));
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($file));
ob_clean();
flush();
readfile($file);
unlink($file);
exit;
}
else {
echo "error not found";
}
?>

Categories