Using a local file as a data source in JavaScript Using a local file as a data source in JavaScript javascript javascript

Using a local file as a data source in JavaScript


Here is the code I used for Firefox, which is not portable, but works:

As OP commented, enablePrivilege() has been deprecated, this should be considered usable. But as my Firefox using previous profile still work with my code, so I dig a little into the prefs.js (as about:config is hiding these settings,) And here is the settings you need you get it work.

user_pref("capability.principal.codebase.p0.granted", "UniversalXPConnect");user_pref("capability.principal.codebase.p0.id", "file://");  // path to the html file.user_pref("capability.principal.codebase.p0.subjectName", "");

And here goes the code:

var File = function(file) {  netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');  var ios = Components.classes["@mozilla.org/network/io-service;1"]                            .getService(Components.interfaces.nsIIOService);  if (!File.baseURI) {    File.baseURI = ios.newURI(location.href.substring(0, location.href.lastIndexOf('/')+1), null, null);    File.baseFolder = File.baseURI.QueryInterface(Components.interfaces.nsIFileURL).file.path;  }  var URL = ios.newURI(file, null, File.baseURI);  this.fptr = URL.QueryInterface(Components.interfaces.nsIFileURL).file;}File.prototype = {  write: function(data) {    netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');    var foStream = Components.classes["@mozilla.org/network/file-output-stream;1"]                             .createInstance(Components.interfaces.nsIFileOutputStream);    foStream.init(this.fptr, 0x02 | 0x08 | 0x20, 0666, 0);    var converter = Components.classes["@mozilla.org/intl/converter-output-stream;1"]                              .createInstance(Components.interfaces.nsIConverterOutputStream);    converter.init(foStream, null, 0, 0);    converter.writeString(data);    converter.close();  },  read: function() {    netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');    var fstream = Components.classes["@mozilla.org/network/file-input-stream;1"]                            .createInstance(Components.interfaces.nsIFileInputStream);    var cstream = Components.classes["@mozilla.org/intl/converter-input-stream;1"]                            .createInstance(Components.interfaces.nsIConverterInputStream);    fstream.init(this.fptr, -1, 0, 0);    cstream.init(fstream, null, 0, 0);    var data = "";    // let (str = {}) { // use this only when using javascript 1.8    var str = {};      cstream.readString(0xffffffff, str);      data = str.value;    // }    cstream.close();    return data;  }};


Here is an example that uses JSON data in an external file that works locally or on a server. This example just uses the browser's language setting to load a < script > with localized html and then processes its json object to reset the data in the indicated tags with localized content

<html><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><head><script>    function setLang(){        for (var i=0;i<items.length;i++){            term=document.getElementById(items[i].id)            if (term) term.innerHTML=items[i].value        }    }    var lang=navigator.userLanguage || navigator.language;    var script=document.createElement("script");    script.src=document.URL+"-"+lang.substring(0,2)+".js"    var head = document.getElementsByTagName('head')[0]    head.insertBefore(script,head.firstChild)</script></head><body onload='setLang()'><div id="string1" class="txt">This is the default text of string1.</div> <div id="string2" class="txt">This is the default text of string2.</div></body></html>

The data files for this look like:

items=[{"id":"string1","value":"Localized text of string1."},{"id":"string2", "value":"Localized text of string2."}];

but you can use any parameter to conditionally load the appropriate file (it will be inserted as the first tag in < head >, so it will be usable in anywhere) and the JSON format is capable of handling a large variety of data. You may want to rename the function setLang to something more appropriate and modify it to meet your needs such as ... for each i add a row, then add fields with the data (it looks like you already have a handle on that part) and your JSON would look like:

items=[{"fname":"john","lname":"smith","address":"1 1st St","phone":"555-1212"},{"fname":"jane","lname":"smith","address":"1 1st St","phone":"555-1212"}];

if you need to preprocess your data, awk is pretty handy - it would be something like: (untested guestimate)

awk 'BEGIN{FS=",";print "items=[\n"}{printf "{\"fname\":\"%s\",\"lname\":\"smith\",\"address\":\"1 1st St\",\"phone\":\"555-1212\"},\n", $1, $2, $3, $4}END{print "];"}' file.csv > file.js

Edit: now that OP is more clear, only mozilla browsers allow XMLHttpRequest on file:// out of the box and chrome (possibly other webkit based browsers) can be configured to allow it. Knowing that it may NOT work on IE<10, you can:

var filePath = "your_file.txt";xmlhttp = new XMLHttpRequest();xmlhttp.open("GET",filePath,false);xmlhttp.overrideMimeType('text/plain');xmlhttp.send(null);//maybe check status !=404 herevar fileContent = xmlhttp.responseText;var fileArray = fileContent.split('\n')var n = fileArray.length;//process your data from here probably using split again for ','

I'm leaving the initial json-p variation for others that may have a similar issue, but have some control of their data format, since it will work on all javascript capable browsers. However, if anyone knows a way to make it work for IE (other than running a small web server), please edit.

Edit 2:

With mozilla browsers you can also use iframes

<html><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><head><script>function showContents(frameObject){    alert(frameObject.contentDocument.body.innerHTML);    //replace with your code}</script></head><body onload='showContents()'><iframe id="frametest" src="data.txt" onload="showContents(this);"     style="visibility:hidden;display:none"></iframe></body></html>


Assuming the csv file is in the same directory as the app, I would load the file with AJAX. As far as I know, one can get the file in text format, and then parse it. This should work in IE and Firefox, but does not work in Chrome (unless one runs chrome with the --allow-file-access-from-files command line setting).