2

I need a way to insert the text downloaded from a .txt file from a URL into an element or variable which i can use further.

I have tried adding the URL to an object element which displays the text correctly, but I do not know how to add this text into a variable.

var storage = firebase.storage();
var storageRef = storage.ref();
var tangRef = storageRef.child('Recs');
var fileRef = tangRef.child("rec3.txt");

    fileRef.getDownloadURL().then(function(url)
    {
        alert(url);
        var para = document.getElementById('p1');
        var par = document.createElement("object");
        par.setAttribute('data', url);
        para.appendChild(par);

    }).catch(function(error) 
    {
        console.error(error);
    });
Doug Stevenson
  • 236,239
  • 27
  • 275
  • 302
Darcia14
  • 149
  • 12
  • Do you have some code ? – ElJackiste Sep 30 '18 at 13:51
  • I have updated and added code – Darcia14 Sep 30 '18 at 13:53
  • 1
    Is the URL to the text file pointing to the same server? If it points to an external server you have to deal with the CORS problem: https://enable-cors.org/ – jg80 Sep 30 '18 at 13:56
  • No the specific file URL is coming from the Firebase Firestore – Darcia14 Sep 30 '18 at 13:59
  • I have read about that, but I am able to see the contents of the file on the ? It is displaying correctly – Darcia14 Sep 30 '18 at 14:00
  • 1
    Is that file URL on the same server as your site or is it something different? For example, say your JS runs on `https://example.com/index.html`, is that file URL something like `https://example.com/file.txt`? – Phil Sep 30 '18 at 14:00
  • Do you have more code ? I am sorry but i still doesn't get what you want to achieve. – ElJackiste Sep 30 '18 at 14:03
  • The URL is https://firebasestorage.googleapis.com/..... – Darcia14 Sep 30 '18 at 14:06
  • 1
    If you are searching to get the content of one remote file you can use XHR or Fetch API. Is it your question ? – ElJackiste Sep 30 '18 at 14:22
  • What attribute will I ask for? getAttribute("data") just gives me the URL back – Darcia14 Sep 30 '18 at 14:25
  • 1
    If you use XHR for example you can get the content of your remote file. – ElJackiste Sep 30 '18 at 14:29
  • 1
    I have tried it, but I always get an xmlhttp.readyState = 4 and xmlhttp.status = 0; – Darcia14 Sep 30 '18 at 14:32
  • 1
    Can you show the code of what you did with xhr ? Your server also need to authorized CORS. For the ready state meaning, check here : https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/readyState – ElJackiste Sep 30 '18 at 14:43
  • 1
    The reason I did not follow through with the CORS thing is that I am already seeing the appended text from the file with my current code. I just do not know how to reference it to use it further. – Darcia14 Sep 30 '18 at 14:47
  • 1
    Yes, because you go through the HTML element object as you could go through a script element. If you want to keep this way, you can get the text content of this element after the appendChild but you will still have a same-origin policy problem. – ElJackiste Sep 30 '18 at 16:20
  • 1
    I can make an answer with code if you want. – ElJackiste Sep 30 '18 at 16:21
  • Please do try, if it works I will accept – Darcia14 Sep 30 '18 at 16:22
  • Looks like you didn't like my answer, so i updated with a working example ;) – ElJackiste Oct 01 '18 at 16:07
  • 1
    I got a workaround working. But thank you very much for your effort. it looks like the correct answer to my question, and if it works it is worth accepting, thank you very much! – Darcia14 Oct 01 '18 at 16:11

2 Answers2

3

As mentionned, you can get some file through an object HTML element as you can do through a script HTML element to load a file. From these elements you won't have a same-origin policy problem, that's why your document is loaded with setAttribute and appendChild.

If you tried to access a resource by XHR or if you tried to interact with a document (both by JS), which are not from the same origin than your current resource, you will need to manage a same-origin policy mechanism see : https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy

You can choose XHR or choose to access the nested document from the object HTML element, in both case you will have the same-origin policy problem. This is for security reasons which are linked with JavaScript.

If you choose nested document you could do something like this :

<div id="p1"></div>

<script>


var url = "https://firebasestorage.googleapis.com/v0/b/ninjatest-1b0ab.appspot.com/o/random%20text%20file.txt?alt=media&token=c09ae3ee-6a01-4f2b-b2b3-2f57ed7ff111";
// or
// var url = "http://localhost:4000/file.txt";

var para = document.getElementById('p1');
var par = document.createElement("object");
par.setAttribute('data', url);
para.appendChild(par);

par.onload = function() {
  var doc = par.contentDocument || par.contentWindow.document;
  var data = doc.body.childNodes[0].innerHTML;

  console.log(data);
};


</script>

If you run this code, you can see that it doesn't accept cross-origin. This is because i'm trying to get a document (nested in the HTML document) which is from another domain. The browser won't let me access it. In the other hand, if i run in local with a node server, it allows me to get it without the error.

If you choose to use XHR (XMLHttpRequest) you can do something like that :

var data;
var url = "https://firebasestorage.googleapis.com/v0/b/ninjatest-1b0ab.appspot.com/o/random%20text%20file.txt?alt=media&token=c09ae3ee-6a01-4f2b-b2b3-2f57ed7ff111";

var xhr = new XMLHttpRequest();

xhr.onreadystatechange = function () {
  if (xhr.readyState === 4) {
    data = xhr.responseText;
    console.log(data);
  }
};

xhr.open('GET', url);
xhr.send();

Again here, it won't work because of the different origin. In the two situations, it's the browser which implements a security rule. You can fix it if you have access to the server part. On the server, you could tell the browser (by HTTP header) to allows client from different origin.

With XHR you need to search about CORS.

With Nested document, you can look here :

If you don't have access to the server part, you could grab the file with a GET request from a server that you own (and so have access to the server part). In this case, you won't have the browser security issue because from your server, you will serve the file without the restriction of same-origin. It will be a proxy server solution.

With Firebase

When you create project with Firebase you can configurate the server part to allow the XHR as mention here : https://firebase.google.com/docs/storage/web/download-files#download_data_via_url

JSON file example :

[
  {
    "origin": ["*"],
    "method": ["GET"],
    "maxAgeSeconds": 3600
  }
]

I created a Firebase account, tried it and it works very well.

Working example with XHR (you can run it) :

var data;
var url = "https://firebasestorage.googleapis.com/v0/b/first-app-a7872.appspot.com/o/firebase.txt?alt=media&token=925fef9e-750e-40e5-aa92-bdfe8204d32e";

var xhr = new XMLHttpRequest();

xhr.onreadystatechange = function () {
  if (xhr.readyState === 4) {
    data = xhr.responseText;
    console.log(data);
  }
};

xhr.open('GET', url);
xhr.send();
ElJackiste
  • 1,914
  • 2
  • 17
  • 28
0

https://codepen.io/anon/pen/JmoqQY?editors=1010

In HTML file:

<div id="p1">
</div>

script

url = "https://firebasestorage.googleapis.com/v0/b/ninjatest-1b0ab.appspot.com/o/random%20text%20file.txt?alt=media&token=c09ae3ee-6a01-4f2b-b2b3-2f57ed7ff111"

    var para = document.getElementById('p1');
    var par = document.createElement("object");
    par.setAttribute('data', url);
    para.appendChild(par);

EDIT: I made a stackblitz to try to see if I could extract the data in the text file into a variable for manipulation. https://stackblitz.com/edit/angular-eyhaj5

I was unable to find a way. Problem is that because of CORS policy in browsers you are not supposed to open files outside of your own site.

To get around this you have to either have to send the URL to a function on your server that downloads the textFile and then makes it accessible in a folder. Or you could set up a proxy server that allows cors. Or you could ask the owner of the text file to make it into an API.

Possibly it was a bad idea to put the textfile in firestorage in the first place. If you are the owner of the text file, it would maybe be better to put the text in a firestore database rather than save it as a textfile.

jg80
  • 191
  • 1
  • 8
  • Just now saw you are trying to get the URL from a promise... What does this line output in your code....it should look like the URL I showed in my example: alert(url); I have a feeling your file reference is pointing the wrong place – jg80 Sep 30 '18 at 14:10
  • What I need to know how to put that .txt output: "just some random text file with some text" into a variable to further manipulate – Darcia14 Sep 30 '18 at 14:11
  • got it...have to experiment in stackblitz to make a similar project. – jg80 Sep 30 '18 at 14:17