42

On the server, there is a text file. Using JavaScript on the client, I want to be able to read this file and process it. The format of the file on the server cannot be changed.

How can I get the contents of the file into JavaScript variables, so I can do this processing? The size of the file can be up to 3.5 MB, but it could easily be processed in chunks of, say, 100 lines (1 line is 50-100 chars).

None of the contents of the file should be visible to the user; he will see the results of the processing of the data in the file.

tshepang
  • 12,111
  • 21
  • 91
  • 136
Woody
  • 421
  • 1
  • 4
  • 3

8 Answers8

40

You can use hidden frame, load the file in there and parse its contents.

HTML:

<iframe id="frmFile" src="test.txt" onload="LoadFile();" style="display: none;"></iframe>

JavaScript:

<script type="text/javascript">
function LoadFile() {
    var oFrame = document.getElementById("frmFile");
    var strRawContents = oFrame.contentWindow.document.body.childNodes[0].innerHTML;
    while (strRawContents.indexOf("\r") >= 0)
        strRawContents = strRawContents.replace("\r", "");
    var arrLines = strRawContents.split("\n");
    alert("File " + oFrame.src + " has " + arrLines.length + " lines");
    for (var i = 0; i < arrLines.length; i++) {
        var curLine = arrLines[i];
        alert("Line #" + (i + 1) + " is: '" + curLine + "'");
    }
}
</script>

Note: in order for this to work in Chrome browser, you should start it with the --allow-file-access-from-files flag. credit.

Shadow The GPT Wizard
  • 66,030
  • 26
  • 140
  • 208
  • 1
    Brilliant trick! I thought I'd go mad trying to load a simple little text file from the same server directory. –  May 27 '13 at 14:28
  • Thanks, since then I also fell for jQuery but this trick is valid anyway. :) – Shadow The GPT Wizard May 27 '13 at 14:29
  • For the special case you have to load files from the file system (your html is not served by a webserver but directly from the file system) you might run into issues with iframes, see http://stackoverflow.com/a/20379650/998938. At least I did for Chrome. For Firefox it worked. – rwitzel Oct 11 '15 at 11:07
  • @rwitzel while true, the question here is clearly about reading from server, which usually means actual web server. – Shadow The GPT Wizard Oct 11 '15 at 12:18
  • 1
    For a file:/// URL to be loaded in Chrome I had to start Chrome with `--allow-file-access-from-files` – EM0 Nov 20 '17 at 15:36
15

Loading that giant blob of data is not a great plan, but if you must, here's the outline of how you might do it using jQuery's $.ajax() function.

<html><head>
<script src="jquery.js"></script>
<script>
getTxt = function (){

  $.ajax({
    url:'text.txt',
    success: function (data){
      //parse your data here
      //you can split into lines using data.split('\n') 
      //an use regex functions to effectively parse it
    }
  });
}
</script>
</head><body>
  <button type="button" id="btnGetTxt" onclick="getTxt()">Get Text</button>
</body></html>
John Hascall
  • 9,176
  • 6
  • 48
  • 72
Amjad Masad
  • 4,035
  • 1
  • 21
  • 20
10

You need to use Ajax, which is basically sending a request to the server, then getting a JSON object, which you convert to a JavaScript object.

Check this:

http://www.w3schools.com/ajax/tryit.asp?filename=tryajax_first

If you are using jQuery library, it can be even easier:

http://api.jquery.com/jQuery.ajax/

Having said this, I highly recommend you don't download a file of 3.5MB into JS! It is not a good idea. Do the processing on your server, then return the data after processing. Then if you want to get a new data, send a new Ajax request, process the request on server, then return the new data.

Hope that helps.

Rafid
  • 18,991
  • 23
  • 72
  • 108
  • 1
    OP seems to have said **only** with javascript :) – Sarfraz Dec 26 '10 at 07:04
  • 4
    Yes, Ajax is a technique not a language, so my answer is still using JavaScript only :-) – Rafid Dec 26 '10 at 07:06
  • 1
    Where did i say it is a language but for ajax you still need **server-side language** :) – Sarfraz Dec 26 '10 at 07:10
  • Oh, I understand you, but I don't think this is what OP wants. How would you get a file from the server without connecting to it? – Rafid Dec 26 '10 at 07:12
  • @Rafid K. Abdullah: Now that's good point I did not focus on :) possibly that's all OP needs. – Sarfraz Dec 26 '10 at 07:15
  • 6
    @Sarfraz: For Ajax you most certainly do not need a server side language! Ajax is dumb. It only loads a text file. If you have something that is **NOT** a plain text file **then** you need a server side language to convert it to plain text in the form of JSON or XML or comma delimited text or a simple string etc. But since the OP does have a text file then all he needs to do is make sure he can access it from his web server. Still, not really a good idea to load a 3.5 MB file. – slebetman Dec 26 '10 at 07:36
  • @slebetman: Yes true agreed, I mis-understood the question initially :) – Sarfraz Dec 26 '10 at 07:38
  • @slebetman. I wouldn't say ajax is "dumb". It's merely a programatic interface for your script to make requests. If AJAX is dumb, then so's your browser. AJAX can fetch anything it want. It's up to the script to handle the data once it's received - there's no difference between fetching a text file, an html file, an xml/json snippet, or some purely binary data like an mp3 or mpg. ajax/browser don't care. it'll just get fetched. – Marc B Dec 26 '10 at 11:08
  • @Marc: `AJAX can fetch anything it want` not really, it can only fetch files. It cannot for example connect directly to MySQL or a Modbus device without some server-side script first massaging the data into text. `It's up to the script to handle the data` which is the definition of dumb - Ajax (XMLHttpRequest, iframe injection etc) does not have an opinion about the meaning of the data it recieves. But this is a good thing. It means that the choice of the data format is up to you unlike SQL or Modbus or HL7. – slebetman Dec 26 '10 at 13:44
  • @slebetman well, AJAX can't connect to MySQL database indeed, but only because no one sane person would share database credentials with clients. If it wasn't a concern, AJAX would certainly have functionality to do that. – Neurotransmitter Aug 17 '16 at 17:27
  • @TranslucentCloud: No, it can't unless you modify MySQL to serve HTTP requests. – slebetman Aug 17 '16 at 20:39
  • @slebetman of course it can't. That's what I am talking about: it can't because there is neither reason, nor demand to be able to do this. – Neurotransmitter Aug 19 '16 at 10:44
8

I used Rafid's suggestion of using AJAX.

This worked for me:

var url = "http://www.example.com/file.json";

var jsonFile = new XMLHttpRequest();
    jsonFile.open("GET",url,true);
    jsonFile.send();

    jsonFile.onreadystatechange = function() {
        if (jsonFile.readyState== 4 && jsonFile.status == 200) {
            document.getElementById("id-of-element").innerHTML = jsonFile.responseText;
        }
     }

I basically(almost literally) copied this code from http://www.w3schools.com/ajax/tryit.asp?filename=tryajax_get2 so credit to them for everything.

I dont have much knowledge of how this works but you don't have to know how your brakes work to use them ;)

Hope this helps!

23k
  • 1,596
  • 3
  • 23
  • 52
Noah Gary
  • 916
  • 12
  • 25
5

It looks like XMLHttpRequest has been replaced by the Fetch API. Google published a good introduction that includes this example doing what you want:

fetch('./api/some.json')
  .then(
    function(response) {
      if (response.status !== 200) {
        console.log('Looks like there was a problem. Status Code: ' +
          response.status);
        return;
      }

      // Examine the text in the response
      response.json().then(function(data) {
        console.log(data);
      });
    }
  )
  .catch(function(err) {
    console.log('Fetch Error :-S', err);
  });

However, you probably want to call response.text() instead of response.json().

Don Kirkby
  • 53,582
  • 27
  • 205
  • 286
2

Just a small point, I see some of the answers using innerhtml. I have toyed with a similar idea but decided not too, In the latest version react version the same process is now called dangerouslyinnerhtml, as you are giving your client a way into your OS by presenting html in the app. This could lead to various attacks as well as SQL injection attempts

1

You need to check for status 0 (as when loading files locally with XMLHttpRequest, you don't get a status and if it is from web server it returns the status)

function readTextFile(file) {
var rawFile = new XMLHttpRequest();
rawFile.open("GET", file, false);
rawFile.onreadystatechange = function ()
{
    if(rawFile.readyState === 4)
    {
        if(rawFile.status === 200 || rawFile.status == 0)
        {
            var allText = rawFile.responseText;
            alert(allText);
        }
    }
}
rawFile.send(null);
}

For device file readuing use this:

readTextFile("file:///C:/your/path/to/file.txt");

For file reading from server use:

readTextFile("http://test/file.txt");
Hisham Muneer
  • 8,558
  • 10
  • 54
  • 79
Rahil Ali
  • 957
  • 10
  • 25
0

I really think your going about this in the wrong manner. Trying to download and parse a +3Mb text file is complete insanity. Why not parse the file on the server side, storing the results viva an ORM to a database(your choice, SQL is good but it also depends on the content key-value data works better on something like CouchDB) then use ajax to parse data on the client end.

Plus, an even better idea would to skip the text file entirely for even better performance if at all possible.

Dwight Spencer
  • 1,472
  • 16
  • 22
  • 2
    I had a lot of trouble parsing the initial paragraph in this answer, but I think I got the gist. Note that the asker said "The format of the file on the server cannot be changed." That's what makes the question interesting. If you change the question to allow a bunch of server-side technology, then it's no longer an interesting question, and your answer (which isn't interesting, either) is one of numerous potential solutions. – sowbug Jun 30 '17 at 18:15