使用window.open()和data:方案打开一个计算的文档。

huangapple go评论59阅读模式
英文:

Opening a computed document using window.open() and data: scheme

问题

我有一个在浏览器中运行的网页它生成一个计算的HTML文档我想在一个新的浏览器标签中打开该文档

简单而不够规范的方法是这样的

```js
const w = window.open('', '_blank');
w.document.open();
w.document.write(htmlContents);
w.document.close();

足够简单。但是这有一些我不喜欢的尴尬后果。主要是,新标签的URL必须指向某个地方,但由于新文档是动态生成的,没有可以指向的地方。如果我不指定URL,它将使用我的网页的URL。因此,如果有人刷新包含生成文档的选项卡,文档将消失,并在其位置加载我的网页的新实例。这会让用户感到困惑。

我认为更适合我的需求的是使用data URI。我只需将整个网页的内容编码到URI本身,并使用window.open()打开该URI。这很丑陋,但在语义上符合我的目标:一个独立的计算文档,由于页面刷新而无法意外导航出去。

我构建了我认为对此的概念非常简单的概念,如下所示:

const doc = encodeURIComponent('<html><body><p>Hello, world!</p></body></html>');
window.open(`data:text/html;charset=utf-8,${doc}`, '_blank');

如果我运行这段代码,一个新窗口在屏幕上闪烁了一帧,然后立即关闭。没有引发错误。

我做错了什么?
1: https://en.wikipedia.org/wiki/Data_URI_scheme


<details>
<summary>英文:</summary>

I have a webpage running in a browser that generates a computed HTML document, and I want to open that document in a new browser tab.

The simple and dirty method is to do this:

```js
const w = window.open(&#39;&#39;, &#39;_blank&#39;);
w.document.open();
w.document.write(htmlContents);
w.document.close();

Easy enough. But this has some awkward consequences that I do not like. Namely, the URL of the new tab has to point somewhere, but there is nowhere to point it at since the new document is computed on the fly. If I specify no URL, it uses the URL of my webpage. So if someone refreshed the tab containing the generated document, the document disappears and a new instance of my webpage loads in its place. This would be confounding to the user.

What I believe better suits my needs is to use a data URI instead. I would simply encode the entire contents of my webpage into the URI itself, and use window.open() to open that URI. It's ugly, but semantically aligned with my goal: a standalone computed document that can't accidentally be navigated out of due to page refreshing.

I constructed what I thought was a trivially simple concept for this, like so:

const doc = encodeURIComponent(&#39;&lt;html&gt;&lt;body&gt;&lt;p&gt;Hello, world!&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;&#39;);
window.open(`data:text/html;charset=utf-8,${doc}`, &#39;_blank&#39;);

If I run this code, a new window flashes on my screen for one frame before immediately closing. No error raised.

What am I doing incorrectly?

答案1

得分: 0

以下是要翻译的内容:

显然,所有现代浏览器故意阻止了这种对Data URIs的使用。太棒了。

在“我最近需要的唯一非常完美的东西被拿走”这个方面,黑板上又多了一个勾号。唉。

好的一面是,这似乎做得比我想要的更好:

const html = '&#39;&lt;html&gt;&lt;body&gt;&lt;p&gt;你好,世界!&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;&#39;';
const blob = new Blob([html], { type: '&#39;text/html&#39; });
const url = URL.createObjectURL(blob);
window.open(url, '&#39;_blank&#39;');
英文:

Apparently all modern browsers have explicitly blocked this use of Data URIs on purpose. Wonderful.

Another tick on the chalkboard for "the singular very perfect thing I needed was taken away from us relatively recently". Ugh.

On the bright side, this seems to do everything I want even better:

const html = &#39;&lt;html&gt;&lt;body&gt;&lt;p&gt;Hello, world!&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;&#39;;
const blob = new Blob([html], { type: &#39;text/html&#39;});
const url = URL.createObjectURL(blob);
window.open(url, &#39;_blank&#39;);

huangapple
  • 本文由 发表于 2023年5月11日 09:41:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/76223596.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定