2

I am saving a file constructed in javascript to the local internet downloads directory.

This works:

javascript

var filename = "mysave.txt"
var contents = "xyz";
document.location = "htmlsave.php?filename=" + filename + "&contents=" + contents;

htmlsave.php:

if(!isset($_GET)) {
    exit(0);
}
$filename = $_GET['filename'];
$contents = $_GET['contents'];

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: application/octet-stream");
header("Content-Disposition: attachment; filename=\"" . $filename . "\";" );
header("Content-Transfer-Encoding: binary");
header("Content-Length: " . strlen($contents));
header("Connection: close");
echo $contents;

This does not:

javascript:

var i;
var filename = "mysave.txt"
var contents = "";
for(i=0, contents = "";i<10000;i++){
    contents += "x";
}
document.location = "htmlsave.php?filename=" + filename + "&contents=" + contents;

This obviously does not work due to the 2K limit on the url.

The error is:

Request-URI Too Long
The requested URL's length exceeds the capacity limit for this server.

Obviously you need to use POST, but how do you do it with POST? How do you do the 'document.location =' bit with POST data? You cannot do an ajax POST, (see below), I have tried it and it does not work.

The failed POST method:

javascript:

var filename = "mysave.txt"
var contents = "";
for(i=0, contents = "";i<10000;i++){
    contents += "x";
}
dataARR = {
    filename: filename,
    contents: contents
};
var dataJSON = JSON.stringify(dataARR);
$.ajax({
    type: "POST", // This for array
    url: "htmlsave.php",
    async: true,
    cache: false,
    crossDomain: false, // This needs to be true for other people
    data: { myJson: dataJSON },

    success: function (data) {
    },
    error: function (XMLHttpRequest, textStatus, errorThrown) {
    }
});

htmlsave.php

if(!isset($_POST) || !isset($_POST['myJson'])) {
    exit(0);
}
$dataTotal = json_decode($_POST['myJson'], true);
$filename = $dataTotal['filename'];
$contents = $dataTotal['contents'];

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: application/octet-stream");
header("Content-Disposition: attachment; filename=\"" . $filename . "\";" );
header("Content-Transfer-Encoding: binary");
header("Content-Length: " . strlen($contents));
header("Connection: close");
echo $contents;

So what can I do to save files greater than 2K?

Rewind
  • 2,554
  • 3
  • 30
  • 56

1 Answers1

1

php is not necessary to create, prompt user to save file created at javascript. You can use <a> element with download attribute set to filename, href set to objectURL of Blob containing file data to initiate prompt for user to save file.

If you want to use php you can utilize php://input, file_get_contents(), echo POSTed Blob or File object.

var i;
var filename = "mysave.txt"
var contents = "";
for(i=0, contents = "";i<10000;i++){
    contents += "x";
}

var data = new Blob([contents], {type:"text/plain"});
var file = URL.createObjectURL(data);
var a = document.createElement("a");
a.download = filename;
a.href = file;
a.click();

Using file_ge_contents(), php://input

javascript

var i;
var filename = "mysave.txt"
var contents = "";
for(i=0, contents = "";i<10000;i++){
    contents += "x";
}

var data = new Blob([contents], {type:"text/plain"});

var request = new XMLHttpRequest();
request.open("POST", "/path/to/server");
request.setRequestHeader("x-file-name", filename);
request.reponseType = "blob";
request.onload = function() {
  console.log(this.response); // `echo`ed file
};
request.send(data);

php

echo file_get_contents("php://input");

See also Generate png-file with php from dataURI sent through ajax ; though note request.setRequestHeader("x-file-name", filename); should have been included at javascript portion of Answer for $tmpFilename = $_SERVER["HTTP_X_FILE_NAME"]; at php

Community
  • 1
  • 1
guest271314
  • 1
  • 15
  • 104
  • 177