James V. Fields
James V. Fields

Reputation: 31

Accessing a local file using HTML/javascript

I am trying to access local files. The method works with Firefox (and was surprised Edge) but not Chrome.

The files in question are 2 html files each containing a huge tables that are used as databases. The tables are basic tables (table, tbody for each group, tr's, and td's with data).

The method I am using is to load the html files into 2 hidden iframes then accessing the tables inside - html file 1 is a master spell list and html file 2 is similar file for a pencil and paper RPG. Works beautifully in Firefox - tables are read into memory, selects/options are all loaded up, popups and page modifications (showing results of what you selected, memory versions of tables modified as needed, generated customized function working - if this file exists at loadup it automatically updates the memory versions of the tables, if the tables are modified - user is shown the function and can copy/save by using a text editor to local file system). Again beautifully.

But Chrome is a different matter. I can load the files in the iframes, but can't access the tables within. It throws an error about cross server access even though all files are in the same directory (the master html file, functions.js file, 2 table files, and if generated and saved by user the customization.js).

So my question is: is there a way to load/import/access a second or third html file in the main html that will work in FF, Chrome, Edge, and most other modern browsers without changing any security settings?

I would love something as simple as how js and the iframe files can be loaded () and accessable. Can xmlrequest work on local files (I could load and render the tables)?

I would like to share the files with the other players, but can't assume browser choices, security settings, and some may not be technically minded enough to make or want said changes.

PS: I am not looking to write any files back to file system, user is the only one with those options.

OK, the other methods (using new tag attributes) failed so looking into a way to hijack the tag and use JSON.

Another user here posted this code (I have cleaned it up - easier to read - and added the suggested but not included part of the code - adding/initializing rowIx and its incrementer)

function getTable() {
  var jsonArr = [];
  var obj = {};
  var jsonObj = {};
  var rowIx = 0
  //this assumes only one table in the whole page, and table has column headers 
  var thNum = document.getElementsByTagName('th').length;
  var arrLength = document.getElementsByTagName('td').length;
  for(i = 0; i < arrLength; i++){
    if(i%thNum === 0){ obj = {}; }
    var head = document.getElementsByTagName('th')[i%thNum].innerHTML; 
    var content = document.getElementsByTagName('td')[i].innerHTML; 
    obj[head] = content; 
    if(i%thNum === 0){ 
      jsonObj[rowIx++] = obj; 
    }
  } 
  return JSON.stringify({"Values": jsonObj}) 
} 

the caller then displays (in a P tag using .innerText since .innerHTML tries to render the data; there are p and br tags in some of the table cells) the returned value so it can be copy/pasted/saved in a separate .js file.

Testing the JSON.parse function in the original HTML (that contains the table I want to later import elsewhere) works just fine, although not like the original: array.Values[x].property vs array.rows[x].cells[y].innerHTML but I can work with that.

format: {"Values":{"numeric index":{7 key/value pairings},{pattern repeated 122 more times}}}

But when the data is placed in a separate js file, it won't parse back to the original data (error is found when developer options/web console is activated, see below).

source HTML file (has the table database, generates the JSON data for copy/paste/save)
large Table (style="display:none;" which hides it, 123 rows by 7 cells each)
the above function getTable
var test1 = getTable()
update p tag using .innerText for copying with test1 data
var schematics = JSON.parse(test1)
alert(schematics.Values[0].Name)  
(all of that works)

js File contents (schematics.json.js)
var schematics = JSON.parse(  copy/pasted data goes here  );

html file
<script language="javascript" src="schematics.json.js"></script>
<script language="javascript">
  alert(schematics.Values[0].name); //data restored test
  function rebuildTable(){
    //use schematics data to rebuild hidden table
  ) 
</script>
<script language="javascript" src="_functions.js"></script>
all other code is in the last script tag

Web Console, reported error
unexpected character at line 1 column 2 of the JSON data

So what am I doing wrong with the JSON containing js file or secondary HTML page?

Upvotes: 1

Views: 4473

Answers (2)

James V. Fields
James V. Fields

Reputation: 31

Ok, found a way that works.

In the two webpages that function as my databases, I added code to read the tables into a 2-dimensional arrays (row by cells).

These are then JSON.stringified and "var variableName = " is tacked on the beginning of the returned strings. All this is then added to a p tag (.innerText since there is also HTML code in the JSON data, rendering is not desired).

The presented data is then copied and saved using a plain text editor in a JSON.variableName.js file (the JSON in the name is to remind me what's in the file). Loading it is as easy as loading javascript code using a script tag with src="".

Also, now everything works in Firefox, Edge, and Chrome. I don't have Safari or other browsers. Bonus for me, it works in Android Firefox as well.

The two database webpages can be easily updated and they will generate the new JSON data output.

All in all, there are 6 base files: the main webpage, functions.js, two JSON variable js files, and the 2 database/JSON generator webpages. All local, and no additional webserver needed.

Upvotes: 0

hunteke
hunteke

Reputation: 3716

This is a difference in the security models and choices of Firefox (and Edge) vs the more strict Chrome. You could argue for the utility vs security of either approach.

To make this work with Chrome the way the other two browsers do, you'll need to disable that security measure with a command line flag when you start Chrome:

> chrome --allow-file-access-from-files

The other alternative is to run a local webserver (e.g. WAMP or XAMPP) and load your files via http://localhost/.

Upvotes: 1

Related Questions