问题
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?
回答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
来源:https://stackoverflow.com/questions/38676275/html-file-save-how-to-overcome-the-2k-limit-on-get-note-post-does-not-work