【问题标题】:How to save data to the browser with data: URL?如何使用 data: URL 将数据保存到浏览器?
【发布时间】:2016-05-22 20:21:44
【问题描述】:

我创建了一个小书签,它尝试使用localStorage 读写,并带有以下data: url:

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

这将在浏览器中转换为以下代码:

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

这段代码尝试将字符串hello world写入浏览器的localStorage,读取字符串最后写入页面。

但是,这会导致以下错误:

未捕获的安全错误:无法从“Window”读取“localStorage”属性:“data:”URL 中的存储已禁用。

由于这种方法不起作用,它给我带来了一个问题:如何使用data: URL 将数据保存到浏览器?除了localStorage,还有其他API 可以用来将数据保存在data: URL 中吗?

编辑:

Cookie 不起作用。尝试访问 cookie 会出现以下错误:

未捕获的 DOMException:无法从“文档”读取“cookie”属性:“数据:”URL 中禁用了 Cookie。

编辑 2:

File system API 也不起作用。因错误对象而失败:

【问题讨论】:

  • 听起来像是 XY 问题。什么是更高级别的用例?
  • 您不能,因为数据 URL 不支持本地存储。 Check this.
  • @charlietfl 创建一个简单的“记事本”,即使在离线或重新启动浏览器时,我也可以将文本内容保存在浏览器中。
  • @TheAlpha 将问题更新为更清晰
  • 我不知道您为什么需要数据 uri,而且似乎无法使用数据 uri。但是,您可以从小书签访问 localStorage,尽管您获取/设置的数据将与您在运行小书签时所在页面的 URL 相关联。只需使用:“ javascript:localStorage.setItem('content', 'hello world'); document.write(localStorage.getItem('content'));”

标签: javascript html browser


【解决方案1】:

为什么不使用 0x0 图像来查询 HTTPS 源,它只是将查询字符串中的数据存储到 cookie,以便您可以通过加载基于 cookie 内容的动态脚本文件来检索它?如果该源缓存自身,它将离线运行。

【讨论】:

  • 欢迎来到 Stack Overflow!我建议不要在答案中使用修辞问题。他们可能会被误解为根本不是答案。
  • 该技术允许您创建跨域存储。我自己从未尝试过,但我知道它会起作用。它使用类似于广告客户跟踪的技术。
  • 我认为这不是对我评论的回答。请edit它进入帖子。
  • 我认为您所描述的是使用服务器将用户提交的数据存储到纯文本 cookie 中?这将需要一个网络连接来保存数据,这是我不想要的(尽管读取也可以离线完成)。
  • 雇佣服务人员怎么样,只要设备在离线之前有互联网就可以访问数据?
【解决方案2】:

我曾经使用这个书签作为浏览器的主页:

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

但 Chrome 似乎不允许从数据 uri 页面中更新位置...

【讨论】:

    【解决方案3】:

    @charlietfl 创建一个简单的“记事本”,即使在离线或重新启动浏览器时,我也可以将文本内容保存在浏览器中。

    解决记事本用例,以下是一个简单的解决方案,它可以脱机工作,当浏览器重新启动时,在多个设备上持续存在(如果您的历史记录在不同的浏览器之间共享)并且您可能会争辩说带来了额外的好处内置的版本控制...

    您可用的一个“存储”机制是实际的 url,因此使用它似乎是一种可能的选择。只要您对在这种情况下更改 url 感到高兴,那么您可以在以下基础上进行构建。

    <!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>
    

    希望对您有所帮助!

    【讨论】:

    • 谢谢,这个答案完美!它实际上将内容存储到浏览器(浏览器的历史数据库),即使我关闭浏览器也可以访问它。我还可以通过为修改后的 URL 添加书签,将内容永久“保存”到浏览器中。
    • 很高兴我能帮助@jehna1!如图所示,您还可以在继续使用代码的同时慢慢增强代码。即添加 #editable:focus {outline:none;} 可能是一个开始。
    • 是的,我正在构建代码。当我完善并准备好书签时,我将开源它:)
    • 如果您可以通过评论告诉我们,那就太好了!我认为这是一个有趣的笔记方向,我一直在寻找一个简单的解决方案来代替 nvALT 等。
    • 完全忘记在这里发布了,但是现在记事本已经发布了,我已经使用了一段时间了。 Github:github.com/jehna/notepadlet 博文:thejunkland.com/blog/…
    【解决方案4】:

    简答:不可能!这是因为出于安全原因,所有存储机制都绑定到源。这是必需的,以便一个页面无法访问另一个页面的数据。在数据 URL 中,您没有来源,那么浏览器应该如何将数据绑定到您的页面?

    长答案:您的用例可能不需要它。我参考你的评论:

    @charlietfl 创建一个简单的“记事本”,即使在离线或重新启动浏览器时,我也可以将文本内容保存在浏览器中。

    这可以更容易地归档!不要为此使用数据 URL!可能您将数据 url 存储为书签,因此无论哪种方式,一旦用户需要访问您的网站以添加此书签。利用这个机会做其他事情:给用户一个带有Application Cache Manifest 的普通网页。这样,您将拥有一个具有所有常用功能的普通页面,例如访问 localStorage,因为您已绑定到源。感谢应用程序缓存清单,此页面将永远不会重新加载。它将在浏览器重新启动后继续存在并完全脱机工作。您只需在第一次访问时连接互联网即可安装该应用程序。

    所有主流浏览器都支持这一点,并且对于您的简单用例而言易于实现!

    【讨论】:

    • 感谢您的回答!这个解决方案首先仍然需要一个 Web 服务器来拥有一个域,但这是一个很好的解决方法。
    【解决方案5】:

    在用户计算机上本地存储信息对于正在为 Web 创建内容的开发人员来说是一种强大的策略。

    如果您使用网络应用程序,那么您有两种类型的网络存储,可帮助您在客户端浏览器中存储和检索数据。 这两个存储是

    1.本地存储
    2. 会话存储

    两个存储都维护一个文件,其中包含键值对对象形式的每个唯一 URL ID 的数据。为此,您可以使用任何存储 localStorage()sessionStorage()

    为每个用户浏览器创建一个唯一的 URL ID,因此当您尝试从这些存储中检索数据时,您需要这个唯一的 URL 来检索数据。如果你不想使用这个唯一的 url,你也可以实现你自己的自定义组合来生成 URL。

    这些存储用于不同的目的并有自己的特点。

    当您将数据存储在 localStorage 中时,您可以在关闭浏览器后随时访问该特定的唯一 URL。

    另一方面,当您使用 sessionStorage 存储和检索数据时,您只能在浏览器打开时访问数据。关闭浏览器时,它将清除您的所有数据。当你回来时,你会发现那个 URL 上什么都没有。和

    现在,从本地存储存储和访问数据的示例。

    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' ) ) );
    

    当您尝试按照 url 存储和访问数据时。

    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);
         });
    }
    

    我希望它能给你一个处理网络存储的想法。有关从 Web 存储存储和访问数据的更多信息。 click here..

    【讨论】:

      【解决方案6】:

      你可以使用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>
      

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

      【讨论】:

      • 这是一个很好的答案,但它仍然需要一个初始源域,其中 blob URL 绑定到。如果我直接从data: URL 运行它,它会给出以下错误: Uncaught SecurityError: Failed to read the 'localStorage' property from 'Window': Access is denied for this document. and the result URL is blob:null/5afcf8cd-10f5-410d-aacb-e5ea4a693495.
      【解决方案7】:

      正如您在几个 cmets 中提到的那样,data: urls 不支持本地存储。这是我们可以给你的唯一答案,因为至少目前大多数浏览器都是这样处理的。

      做出该设计决定的原因似乎是因为本地存储与文档的来源相关联,因此我的网站无法访问 google.com 等设置的本地存储。对于 data: urls there不是任何有意义的词源。 file: url 在某些浏览器中启用了本地存储(我相信 Firefox 肯定,我不知道 Chrome),因为来源至少是本地文件系统。一个 data: url 没有来源,所以没有方案对其本地存储数据进行排序。

      就目前而言,Chrome 已宣布这是预期行为,除非本地存储规范更新为明确说明,否则他们不太可能更改它,Firefox 似乎也以同样的方式倾斜,而我没有知道 IE,但他们很可能已经效仿。

      【讨论】:

      • 除了localStorage 之外,是否还有其他API 可用于在data: url 中保存数据?
      • 您可以尝试使用 JavaScript 设置 cookie,但我相信这些也与来源相关联。我不确定它会如何表现。
      • 由于我的问题是关于“如何保存数据”而不是“为什么这段代码不起作用”,很遗憾我不能接受你的回答。如果您使基于 cookie 的方法正常工作并更新您的答案以包含工作演示,我很乐意接受它
      • @jehna1 你可以接受这篇文章,因为它解释了为什么你想要的东西是不可能的(出于安全原因)。我怀疑你永远不会接受一个工作演示。
      • 如果你再给我一天左右的时间,我可以看看 cookie 或任何其他技术是否允许浏览器存储数据:url。
      【解决方案8】:

      data: urls 不支持本地存储。如果您真的想将数据存储到客户端设置的 cookie,这是唯一的方法。

      【讨论】:

      • 你能提供一个工作代码吗?正如我在问题中所述,访问 document.cookie 会引发类似 localStorage 的错误。
      • 看到这个Link希望这对你有帮助
      • 那个链接指向一个描述 PHP 的setcookie 函数的页面?那是服务器端,所以很遗憾它没有帮助。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-09-24
      • 2023-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-10
      相关资源
      最近更新 更多