简体   繁体   中英

How to save data to the browser with data: URL?

I have created a bookmarklet that tries to read and write with localStorage with the following data: url:

data:text/html;base64,PGRvY3R5cGUgaHRtbD4KPGh0bWw+Cjxib2R5Pgo8c2NyaXB0Pgpsb2NhbFN0b3JhZ2Uuc2V0SXRlbSgnY29udGVudCcsICdoZWxsbyB3b3JsZCcpOwpkb2N1bWVudC53cml0ZShsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnY29udGVudCcpKTsKPC9zY3JpcHQ+CjwvYm9keT4KPC9odG1sPg==

This translates to following code in the browser:

<doctype html>
<html>
<body>
<script>
localStorage.setItem('content', 'hello world');
document.write(localStorage.getItem('content'));
</script>
</body>
</html>

This code tries to write the string hello world to the browser's localStorage, read the string and finally write it to the page.

However, this results in the following error:

Uncaught SecurityError: Failed to read the 'localStorage' property from 'Window': Storage is disabled inside 'data:' URLs.

As this approach doesn't work, it brings me to the question: How to save data to the browser with data: URL? Is there some other API than localStorage that I could use to save data in data: URLs?

EDIT:

Cookies do not work. Trying to access cookies gives the following error:

Uncaught DOMException: Failed to read the 'cookie' property from 'Document': Cookies are disabled inside 'data:' URLs.

EDIT 2:

File system API does not work either. Fails with the error object:

文件错误

@charlietfl Creating a simple "notepad" where I could persist textual content in the browser even when offline or when the browser is restarted.

Working off the notepad use case, the following is a simple solution which works offline, when the browser restarts, persists across multiple devices (if you have your history shared across your different browsers) and you could argue comes with the added bonus of versioning built in...

One 'storage' mechanism you have available is the actual url so using it seems like a possible choice. As long as your happy for the url to change in this situation then you could build on top of the following.

<!doctype html>
<html>
<body>
<div id="editable" contenteditable="true">
    My notepad!
</div>
<script>
    document.getElementById('editable').addEventListener('blur', function (event) {
        window.location = 'data:text/html;base64,' + btoa(document.documentElement.outerHTML);
    });
</script>
</body>
</html>

Hope this help!

You can use Blob() , URL.createObjectURL()

<!DOCTYPE html>
<html>
<head>
  <script>
    window.onload = function() {
      var html = "<!doctype html>\
                   <html>\
                     <body>\
                       <script>\
                         localStorage.setItem('content', 'hello world');\
                        document.write(localStorage.getItem('content'));\
                      <\/script>\
                     </body>\
                   </html>"
      , blob = new Blob([html], {
        type: "text/html"
      })
      , url = window.URL.createObjectURL(blob)
      , a = document.getElementById("bookmark");
      a.href = url;
    }
  </script>
</head>
<body>
  <a id="bookmark" target="_blank">click</a>
  </body>
</html>

plnkr http://plnkr.co/edit/EyzUwJrlgD7GTNWnfjwe?p=preview

Short answer: Its not possible! This is because all storage mechanisms are bound to the origin for security reasons. This is required so that one page can not access the data of another. In a data URL you don't have an origin, so how should the browser bound the data to your page?

Long answer: You probably don't need it for your use case. I refer you comment:

@charlietfl Creating a simple "notepad" where I could persist textual content in the browser even when offline or when the browser is restarted.

This can be archived much easier! Don't use a data URL for this! Probably you store the data url as a bookmark, so either way once the user need to access your website to add this bookmark. Use that occasion to do something else: Give the user a normal webpage with an Application Cache Manifest . With that you will have a normal page with all the usual abilities like access to the localStorage because you are bound to an origin. Thanks to the Application Cache Manifest this page will never reload. It will survive a browser restart and works completely offline. You just need internet on the first visit to install the app.

This is supported by all major browsers, and for your simple use-case easy to implement!

I used to use this bookmarklet as my browser's homepage:

data:text/html, <body contenteditable onblur="window.location='data:text/html;base64,'+btoa(document.documentElement.outerHTML);"/>

But Chrome does not seem to allow updating location from within data uri pages...

As was mentioned in a few comments on your question, local storage isn't supported in data: urls. That's the only answer we can give you, because at least at the moment that is the way most browsers handle that.

The reason for that design decision seems to be because local storage is tied to the origin of the document, so that my website can't access local storage set by google.com, etc. In the case of data: urls there isn't an origin in any meaningful sense of the word. file: urls have local storage enabled in some browsers (I believe Firefox for sure, I don't know about Chrome) because there the origin is at least the local filesystem. A data: url has no origin, so there is no scheme by which to sort its local storage data.

As it stands, Chrome has declared this to be the intended behavior and they are not likely to change it unless the local storage spec is updated to explicitly say otherwise, Firefox seems to be leaning the same way, and I don't know about IE, but they're likely to have followed suit.

local storage is not supported in data: urls. if you really want to store the data to client side set cookies this is the only way to do this.

Why not use 0x0 images to query a HTTPS origin that simply stores data in a query string to a cookie so you can retrieve it by loading a dynamic script file based on the cookie content? If that origin caches itself, it will run offline.

Storing information locally on a user's computer is a powerful strategy for a developer who is creating something for the Web.

if you working on a web application then you have two types of web storage which helps you can store & retrive the data in Client Browser . these two storage are

1. Local Storage
2. Session Storage

Both of the storage maintain a file which contain data per Unique URL ID in object form of key value pair. for this purpose you can use any storage localStorage() or sessionStorage() .

for every user browser creates a unique URL ID so when you trying to retrieve the data from these storage you need this unique URL to retrieve the data. if you don't want to use this unique url you can also implement your own custom combination for generate URL.

These storages is used for different purposes & have their own features.

when you store your data in localStorage then you can access any time when you come back after closing the browser by follow that particular Unique URL.

On the Other hand when you are using sessionStorage for store & retrieve data then you can access data only whenever browser is open. when closing the browser it will clear your all data. and when you come back you will be found nothing is exist on that URL. and

Now, example for store & access the data from localstorage.

var car = {};
car.wheels = 4;
car.doors = 4;
car.sound = 'Boss';
car.name = 'Audi R8';
localStorage.setItem( 'car', JSON.stringify(car) );
console.log( JSON.parse( localStorage.getItem( 'car' ) ) );

when you try to store & access the data by following the url then.

if(localStorage && localStorage.getItem('car')){
    console.log(JSON.parse(localStorage.getItem('car')));
}else{
     $.getJSON("http://query.yahooapis.com/xyz?user1",function(data){
        if(localStorage){
            localStorage.setItem('car',JSON.stringify(data));
        }
        console.log(data);
     });
}

Well i hope it will giving you an idea to deal with web storages. for more information about store & access data from web storage. click here..

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