1

So, I've been working on a page that uses only local files (server is not an option, unfortunately. Not even a localhost. The struggle is real.) and I've come to a situation where I need to grab text from a .csv file and populate it to the page. I have this bit of code that works, but I need to have a file set within the function when a button is pressed. Looking up the file manually isn't an option (to visualize what I'm doing, I'm making a mock database file in the most annoying way possible (because I have to, not because I want to)).

In the page I would have something like:

<button id="myButton" onclick="getText()"></button>

<script>
var myFile = "dataset.csv";
...
</script>

The following bit of code works (in regards to having it pull the data from the csv file), but, as I said, I need to pull the text from the file when a button is pressed and just have the file name set in the script, not pulling it up manually.

<!DOCTYPE html>
<html>
   <body>
      <input type="file" id="fileinput" />
      <div id="outputdiv"></div>
      <script type="text/javascript">
           function readSingleFile(evt) {
             var f = evt.target.files[0]; 
             if (f) {
               var r = new FileReader();
               r.onload = function(e) { 
                  var contents = e.target.result;
                      var splited = contents.split(/\r\n|\n|\r|,/g);
                      for (i=0; i<splited.length; i++){
                         document.getElementById("outputdiv").innerHTML = document.getElementById("outputdiv").innerHTML + splited[i] + "<br>";
                      }     
                     }
               r.readAsText(f);
             } else { 
               alert("Failed to load file");
             }         
           }
           document.getElementById('fileinput').addEventListener('change', readSingleFile, false);
      </script>
   </body>
</html>

From what I can tell from the API, I would need to set the file attributes to a blob in order to pass it to FileReader. How I can do this without using an input box, I have no idea. There's also a 50% chance that I am completely wrong about this since I obviously don't know how to get this done.

If someone could show me how to achieve this with regards to what I'm looking for, it would be very much appreciated. I'm absolutely stumped.

Thank you.

  • First of all, Welcome to Stack Overflow! ... should you use FileReader ? Or you can use something else like ajax to load the data from the csv file ? – xTrimy Mar 08 '19 at 21:32
  • Thanks! I usually find what I need so the fact that I had to make an account to ask this question is driving me crazy. Correct me if I'm wrong, but doesn't Ajax and XML require a server to get the file? I know I tried it, and there was a reason it didn't work, but it's buried under 500 other things that also didn't work. I don't have a good answer for you on that one. – Thomas Patton Mar 08 '19 at 21:37

1 Answers1

1

Note: CORS restrictons will prevent this from working in most browsers. You can use FireFox Developer Edition, which disables CORS validation.

You can use an XMLHttpRequest to load a local file:

<!DOCTYPE html>
<html>
   <body>
      <button onclick="readSingleFile()">Click Me</button>
      <div id="outputdiv"></div>
      <script type="text/javascript">
         function readSingleFile() {
            let xhr = new XMLHttpRequest();
            let url = "relative/path/to/file.txt;
            if (!url) return;
            xhr.onload = dataLoaded;
            xhr.onerror = _ => "There was an error loading the file.";
            xhr.overrideMimeType("text/plain");
            xhr.open("GET",url);
            xhr.send();
          }

          function dataLoaded(e){
            var contents = e.target.responseText;
            var splited = contents.split(/\r\n|\n|\r|,/g);
            for (i=0; i<splited.length; i++){
              document.getElementById("outputdiv").innerHTML = document.getElementById("outputdiv").innerHTML + splited[i] + "<br>";
            }
      </script>
   </body>
</html>
Noah B
  • 193
  • 6
  • Ah, I get to be annoying. Firefox is also not an option. The people I'm making this page for are 100% Chrome, so I don't believe this is a viable solution. Sorry. Like I said, "because I have to, not because I want to" lol – Thomas Patton Mar 08 '19 at 21:41
  • I don't think what you want to do is possible with just Javascript then. You can disable CORS security in Chrome inorder to run the above script, but I do not recommend it: https://stackoverflow.com/questions/3102819/disable-same-origin-policy-in-chrome – Noah B Mar 08 '19 at 21:48
  • You know, I was almost at that point about an hour ago but I realized that if I can do this by getting the file through an input box then I should be able to do whatever the input box is doing with the file within a function without using the input box. Just my thoughts. – Thomas Patton Mar 08 '19 at 21:57
  • 1
    You can't it's a HUGE security hole. You could read any file on a user's machine if that was the case. – Noah B Mar 08 '19 at 22:00