Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

File API, Persistent link to a local file

I'm currently working on some web script based on a game (to port a game to the web). The scripts download data from my web host so the loading is slow (have to download each files : maps, models, textures, ...). To correct this, I added an option that allow users to select their local game data in their computer (using the File API - drag and drop) to parse content directly from local and avoid downloading multiple megas from the web, the result is incredibly fast.

Here the problem : each time they reload the browser, they have to re-select their files, again and again. It's not user-friendly.

So, is there a way to keep a reference from this game archive to avoid the user to re-do the drag and drop each time ? I know about security concern, just want to know if there is something like a persistent URL.createObjectURL().

Note: the game data is about ~2Go, so it's not possible to store it in the FileSystem API (and I don't want to copy it, it's waste space to copy data when you can just keep a reference to it).

Thank you :)

like image 938
Vincent Thibault Avatar asked Dec 10 '12 17:12

Vincent Thibault


People also ask

Can JavaScript access local files?

Web browsers (and JavaScript) can only access local files with user permission. To standardize file access from the browser, the W3C published the HTML5 File API in 2014. It defines how to access and upload local files with file objects in web applications.

How do I open a local file in HTML?

HTML can be used to open a folder from our local storage. In order to open a folder from our local storage, use 'HREF' attribute of HTML. In the HREF attribute, we specify the path of our folder.

Can you access file system from browser?

Web browser can't access OS's file system without direct user permission. Consequently, web apps that use browser-side JavaScript don't have permission to write to the client SSD without a lot of security options having to be disabled.


2 Answers

You have to have an input from the user

It is not possible to access the files on a client's computer without the user confirming it. Once the user chooses a file (You can listen to it with the change event), you can then use the FileReader API for example to read the file.

document.getElementById("input").addEventListener("change", function() {
    const fs = new FileReader();
    fs.readAsText(this.files[0]);
    fs.onloadend = function() {
        document.getElementById("output").innerText = fs.result;
    }
});
<input id="input" type="file" />
<div id="output"></div>

Using localStorage to store a fraction of your files

You could use the localStorage API to store some of your files, but the capacity is very limited, especially for a project like yours (maximum of 5 to 10 MB on current most popular browsers).

This would make your coding much harder, as you would have to check every time what was stored or not, and load what is not saved.

Caching

By using caching, you basically fall into the same problem as you are with localStorage: each browser has its own maximum capacity.

The advantage of this method is that you do not have to worry about what has been loaded or not, as the browser will do this by itself.

Using Flash

Now if you really do not care at all about security, you could use a Flash plugin to store and load the files, and then use ExternalInterface to load the data in your JavaScript code.

ExternalInterface.call("loaded", filename, data);

// And then in JavaScript:
// function loaded(filename, data)
// ...

You could use SharedObject to save and load your data.

I am not an AS3 expert, please excuse any clumsiness.

A Desktop application?

Last option would be converting and bundling your game into a desktop application, for example by bundling it through electron, and then using for example NeDB, which is currently the suggested tool by electron for persistant storage.

like image 116
nicovank Avatar answered Oct 07 '22 17:10

nicovank


You may want to consider using IndexedDB. It is supported in recent browsers including Chrome, Firefox, and Safari (macOS and iOS). IndexedDB allows you to save Blob, File or ArrayBuffer as values in an IndexedDB object store.

Check this IndexedDB: Store file as File or Blob or ArrayBuffer. What is the best option?.

like image 20
yuxhuang Avatar answered Oct 07 '22 15:10

yuxhuang