How to write file in javascript from browser

I have created addons for firefox to scrape google search page web links.

addonsFolder
    manifest.json
    scrape.js

This is my main program file:

let webNum = 5;

function scrapeLinks(num){
    let links = document.querySelectorAll('.yuRUbf a'), hrefs = [];
    for (let i = 0; i < num; i++) { hrefs.push(links[i].href) };
    return hrefs.join(" ");
};
const allLinks = scrapeLinks(webNum);

const fs = require("fs");

function writeInFile(content){
    fs.writeFileSync("H:/python projects/Rafiq A.I/scrape addons/data/weblinks.txt", content, err => {
        if (err) {
        console.error(err);
        };
    });
};

writeInFile(allLinks);

I scrape all website links from the google search page and store them on allLinks variable. It works I check it on the console. But my writeInFile function does not work in the browser. But it works when I run it on the node js terminal. I want to make a program to scrape my data and store it on the txt file. How can I do this?

For security reasons, JavaScript in a browser does not have direct access to your filesystems. But you can get your browser to save the file with the approval and interaction of the end-user. Your code will not be able to choose WHERE the file is saved, and will not be able to directly load the file back in the future. The end-user must do all that “by hand” when the file is saved and then re-loaded in the future. In essence, the browser will present a filesystem window to the user, and be the middle-man between your script and the system.

First you must create a “blob” from the file data using the File constructor. Then you must create an “ObjectURL” from the blob. Then you pass this ObjectURL to an HTML anchor- or iframe-element in your web-page.

The File “blob” should also have the proper mimeType set depending on what you want to do with your file. If you don’t want the browser to open it (it seems that you do not) and you simply want to save the file locally, the mimeType should be one that the browser does not recognize as render-able (i.e. not a .txt .htm .pdf etc.). If it is normally render-able, your mimeType should be “application/unknown” so the browser won’t try to open it. On the other hand, if you want the end-user to see the data before saving it, give the browser the correct file type (mimeType) that it CAN render; the end-user can still opt to save the file with an additional step using the browser’s normal functionality (you can always save any web-page / file you open), but that may be less obvious to some users.

Now-a-days, the anchor element <a> has a download attribute. Back in the day it did not, and I used an iframe element that I hid from the end-user using CSS (nothing to see there, just for functionality). You simply set the href of the anchor, or the src of the iframe. With the anchor, you must then also initiate the process with a synthetic “click” event.

saveFile=function(data, fileName, fileType)  {
  const anchor=document.getElementById('local_filesaver') || document.createElement('a');
  var mimeType;
	switch (filetype)  {
    case 'txt': 
    case 'htm': 
    case 'html': 
    case 'pdf': 
    case 'htm': 
    case 'js':
    case 'json': mimeType="application/unknown";
		break;
		default: mimeType="";  }
  data=new File([data], filename + "." + fileType, {type: mimeType});
  const url=URL.createObjectURL(data);
  if (!anchor.id)  {
    anchor.id='local_filesaver';
		anchor.download=true;
		anchor.target='_blank';
    anchor.style.display='none';
    document.body.appendChild(anchor);  }
  anchor.setAttribute('href', url);
  anchor.click();
  URL.revokeObjectURL(url);  }
	
saveFile=function(data, fileName, fileType)  {
	//use the iframe if you want to target dinosaur browsers; it works with new browsers also
  const iframe=document.getElementById('local_filesaver') || document.createElement('iframe');
  var mimeType;
	switch (filetype)  {
    case 'txt': 
    case 'htm': 
    case 'html': 
    case 'pdf': 
    case 'htm': 
    case 'js':
    case 'json': mimeType="application/unknown";
		break;  
		default: mimeType="";  }
  data=new File([data], fileName + "." + fileType, {type: mimeType});
  const url=URL.createObjectURL(data);
  if (!iframe.id)  {
    iframe.id='local_filesaver';
    iframe.style.display='none';
    document.body.appendChild(iframe);  }
  iframe.setAttribute('src', url);
  URL.revokeObjectURL(url);  }

Keep in mind that these functions will inject the elements they create into the end of your document, if they don’t find them in your document already. This injection can cause havoc if your CSS is not structured correctly. You can hide them with CSS like so:

#local_filesaver {
  display: none;
  position: fixed;
  top: -1000px;
  left: -1000px;
  width: 1px;
  height: 1px; }

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.