Reputation: 2381
I'm making an export function to a HTML5 game of mine and my current saving method is a crude serialization of game data and then:
// this is Javascript
var gameData = "abc"; // this is actually a HUGE string of over 2MB
try
{
document.location = "data:text/octet-stream,"+encodeURIComponent(JSON.stringify(gameData));
}
catch(e)
{
console.log(e);
}
From: Using HTML5/Javascript to generate and save a file
I don't mind the fact that I can't use it for big strings, but I'd like it to generate a warning that informs that this method doesn't work, unfortunately Chrome (16) crashes without catching that exception.
Is there a better way to implement this kind of export, the important thing being for me is to make it work locally. FileAPI would be a better solution, but doesn't work locally.
Upvotes: 6
Views: 2536
Reputation: 6444
I assume that the json.stringify is working But that the win.location fail due to the fact that the URI is to big.
What you can do is to convert your uri to a blob, and then
URL.createObjectURL(file)
This will create a url that point to an internal object (internal to the browser).
And it will work as expected.
Here is a a method to convert dataURI to blob
function(dataURI) {
// convert base64 to raw binary data held in a string
// doesn't handle URLEncoded DataURIs
var byteString;
if (dataURI.split(',')[0].indexOf('base64') >= 0)
byteString = atob(dataURI.split(',')[1]);
else
byteString = unescape(dataURI.split(',')[1]);
// separate out the mime component
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
// write the bytes of the string to an ArrayBuffer
var ab = new ArrayBuffer(byteString.length);
var ia = new Uint8Array(ab);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
// write the ArrayBuffer to a blob, and you're done
return new Blob([ab],{type: mimeString});
}
}
Upvotes: 0
Reputation: 8243
AFAIK not possible client-side; but a 1.99MB file can be saved this way in Chrome; maybe you should try to compress/optimize your game data a little bit. One way to do that is to use JSZip.
In order to check if the current browser is Google Chrome and so the method doesn't work with long strings you can use something like this:
if(gameData.length > 1999999 && window.chrome){
alert("Sorry, this export method does not work in Google Chrome")
return;
}
Upvotes: 1