简体   繁体   中英

Save HTML locally with Javascript

I do know that Javascript cannot write data in the filesystem, for security reasons. I have often read that the only way to save data locally with Javascript is cookies or localStorage .

But is it possible, in the very specific case when the file is accessed locally (and not through internet) to write data locally ? ( without any server language, and even without any server at all... just local browsing of a HTML file )

For example, would it be possible, by clicking on SAVE here on this page ...

...that the HTML file is overwritten with its new content ? (ie the local HTML file should be updated when SAVE is pressed).


在此处输入图片说明


Is this possible to SAVE a file thanks to Javascript, when the HTML page is accessed locally?

Note: I want to be able to silently save , not propose a Download/Save dialog box in which the user has to choose where to download, then "Are you sure to want to overwrite" etc.


EDIT : Why this question? I would like to be able to do a HTML/JS notepad that I can run locally without any server (no apache, no php). I need to be able to save easily without having to deal with Dialog Box "Where do you want to download the file?".

You can just use the Blob function:

function save() {
  var htmlContent = ["your-content-here"];
  var bl = new Blob(htmlContent, {type: "text/html"});
  var a = document.createElement("a");
  a.href = URL.createObjectURL(bl);
  a.download = "your-download-name-here.html";
  a.hidden = true;
  document.body.appendChild(a);
  a.innerHTML = "something random - nobody will see this, it doesn't matter what you put here";
  a.click();
}

and your file will save.

The canonical answer, from the W3C File API Standard :

User agents should provide an API exposed to script that exposes the features above. The user is notified by UI anytime interaction with the file system takes place, giving the user full ability to cancel or abort the transaction. The user is notified of any file selections, and can cancel these. No invocations to these APIs occur silently without user intervention.

Basically, because of security settings, any time you download a file, the browser will make sure the user actually wants to save the file. Browsers don't really differentiate JavaScript on your computer and JavaScript from a web server. The only difference is how the browser accesses the file, so storing the page locally will not make a difference.

Workarounds: However, you could just store the innerHTML of the <div> in a cookie. When the user gets back, you can load it back from the cookie. Although it isn't exactly saving the file to the user's computer, it should have the same effect as overwriting the file. When the user gets back, they will see what they entered the last time. The disadvantage is that, if the user clears their website data, their information will be lost. Since ignoring a user's request to clear local storage is also a security problem, there really is no way around it.

However, you could also do the following:

  • Use a Java applet
  • Use some other kind of applet
  • Create a desktop (non-Web based) application
  • Just remember to save the file when you clear your website data. You can create an alert that pops up and reminds you, or even opens the save window for you, when you exit the page.

Using cookies: You can use JavaScript cookies on a local page. Just put this in a file and open it in your browser:

<!DOCTYPE html>
<html>

<head>
</head>

<body>
  <p id="timesVisited"></p>
  <script type="text/javascript">
    var timesVisited = parseInt(document.cookie.split("=")[1]);
    if (isNaN(timesVisited)) timesVisited = 0;
    timesVisited++;
    document.cookie = "timesVisited=" + timesVisited;
    document.getElementById("timesVisited").innerHTML = "You ran this snippet " + timesVisited + " times.";
  </script>
</body>

</html>

Yes, it's possible.

In your example, you are already using ContentEditable and most of tutorials for that attribute have some sort of localStrorage example, ie. http://www.html5tuts.co.uk/demos/localstorage/

On page load, script should check localStorage for data and if true, populate element. Any changes in content could be saved in localStorage when clicking save button (or automatically, in linked example, using blur and focus). Additionally you can use this snippet to check weather user is online or offline and based on state modify your logic:

// check if online/offline
// http://www.kirupa.com/html5/check_if_internet_connection_exists_in_javascript.htm
function doesConnectionExist() {
    var xhr = new XMLHttpRequest();
    var file = "http://www.yoursite.com/somefile.png";
    var randomNum = Math.round(Math.random() * 10000);

    xhr.open('HEAD', file + "?rand=" + randomNum, false);

    try {
        xhr.send();

        if (xhr.status >= 200 && xhr.status < 304) {
            return true;
        } else {
            return false;
        }
    } catch (e) {
        return false;
    }
}

EDIT: More advance version of localStorage is Mozilla localForage which allows storing other types of data besides strings.

You could save files, and make it persistent using the FileSystem-API and webkit. You would have to use a chrome browser and it is not a standards technology but I think it does exactly what you want it to do. Here is a great tutorial to show how to do just that http://www.noupe.com/design/html5-filesystem-api-create-files-store-locally-using-javascript-webkit.html

And to show that its on topic it starts off showing you how to make the file save persistent...

window.webkitRequestFileSystem(window.PERSISTENT , 1024*1024, SaveDatFileBro);

Convert your HTML content to a data uri string, and set as href attribute of an anchor element. Don't forget to specify a filename as download attribute.

Here's a simple example:

<a>click to download</a>
<script>
    var anchor = document.querySelector('a');
    anchor.setAttribute('download', 'example.html');
    anchor.setAttribute('href', 'data:text/html;charset=UTF-8,<p>asdf</p>');
</script>

Just try it in your browser, no server required.

Have a look into this :) Download File Using Javascript/jQuery there should be everything you need. If you still need help or it's not the solution you need, tell me ;)

I think it's important to clarify the difference between server and client in this context.

Client/server is a program relationship in which one program (the client) requests a service or resource from another program (the server).

Source:http://searchnetworking.techtarget.com/definition/client-server

I'm not sure you'll find too many advanced applications that don't have at least one server/client relationship. It is somewhat misleading to ask to achieve this without any server, because any time your program speaks to another program, it is a client/server relationship , with the requester being the client and the response coming from the server. This is even if you are working locally. When you want to do something outside of the scope of the browser, you need a hook in a server.

Now, that does not mean you can't achieve this without a server-side specific language. For example, this solution uses NodeJS for the server. WinJS has WinJS.xhr, which uses XmlHttpRequest to serve data to the server.

AJAX seeks to offer the same sort of functions. The point here is that whether you have a program or there is some sort of hook pre-built, when you issue a command like " save file " and the file actually gets saved, there is a program on the other side that is parsing it, whether it's a server-side language or something else, meaning you can't possibly have something like this function without a server to receive the request.

Just use https://github.com/firebase/firepadSee it in action
This doesn't need a server on your computer, it will reach out and save the data remotely.

Yes, it is possible. Proof by example:

TiddlyFox: allows modification of local files via an add-on. ( source code ) ( extension page ):

TiddlyFox is an extension for Mozilla Firefox that enables TiddlyWiki to save changes directly to the file system.

Todo.html: An HTML file that saves edits to itself. Currently, it only works in Internet Explorer and you have to confirm some security dialogs when first opening the file. ( source code ) ( functional demo ).

Steps to confirm todo.html actually saves changes to itself locally:

  1. Save todo.html to local harddrive
  2. Open with Internet Explorer. Accept all the security dialogs.
  3. Type command todo add TEST (todo.html emulates the command-line interface of todo.txt-CLI )
  4. Inspect todo.html file for addition of 'TEST'

Caveats: there is no cross-platform method. I'm not sure how much longer these methods will exist. When I first started my todo.html project, there was a jQuery plugin called twFile that allowed cross-browser loading/saving of local files using four different methods (ActiveX, Mozilla XUL, Java applet, Java Live Connect). Except for ActiveX, browsers have disallowed all these methods due to security concerns.

Use jsPDF -> https://github.com/MrRio/jsPDF

<div id="content">
     <h3>Hello, this is a H3 tag</h3>
    <p>a pararaph</p>
</div>
<div id="editor"></div>
<button id="cmd">generate PDF</button>

Javascript

  var doc = new jsPDF();
  var specialElementHandlers = {
      '#editor': function (element, renderer) {
          return true;
      }
  };

  $('#cmd').click(function () {
      doc.fromHTML($('#content').html(), 15, 15, {
          'width': 170,
              'elementHandlers': specialElementHandlers
      });
      doc.save('sample-file.pdf');
  });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM