data:text/html;base64,PGh0bWwgY29udGVudGVkaXRhYmxlPmVkaXQgbWU8L2h0bWw+
复制到浏览器即可使用,可加书签,可分享,不需要网络,全平台可用
有时候需要有个地方临时复制粘贴一些东西,这时候可以用记事本,但是记事本或者其他文本编辑软件关闭时一般需要确认是否保存,且这些临时内容会和工作内容混合
还有个问题是记事本页面不够大,ui 也略复杂一点
这个网页版记事本就能支持这种场景,原则上不支持保存,随用随关,铺满全屏
而且我觉得最有意思的点是,这其实是一个彻底开源极端易于分享的软件形式,软件所有内容都塞到 url 数据里,所见即所得,无需安装,适配全平台,用户还能随时修改逻辑,无需网络,没有服务器成本
缺点是软件大小有限制 以及软件作者可能不太好赚钱
101
kenvix 2023-06-01 22:05:46 +08:00
不怕链接复杂,但是没有自动保存到 localstorage 有点没用
|
102
jaylee4869 2023-06-01 23:03:21 +08:00
几年前在 GitHub 也找到过类似项目,有人把文本放在了 URL 中做成静态网站,
https://itty.bitty.site/edit 最近作者加上了密码保护功能。我自己也部署了一套。 https://txt.lawrenceli.me/Magic/d/Inside-URL/f/%F0%9F%98%85/#/data:text/html;charset=utf-8;cipher=aes-gcm;style=default;format=gz,JS5QNsbLGVe92kEnghtrO7NoFiSczikuuzlrc3vfW09WJKKMtnFzmE8bHMvnVxqfAzykZhqIVNkmquWmfhikh++7MMM1diL3f2xbHvZBfUFu0Uh2qoibwb+NlOIawZYbn8TemA== 密码 V2EX |
103
meeop OP @Cheons 这确实是一个挺重要的应用场景,而且不管能分享文本,还能分享图,不考虑大小的话理论上啥都能分享。比那种。 www 点 xxx 点 xxx 。 需要手动替换字符才能浏览的规避监管文本体验好
|
104
meeop OP @Cheons 这确实是一个挺重要的应用场景,而且不管能分享文本,还能分享图,不考虑大小的话理论上啥都能分享。比那种。 www 点 xxx 点 xxx 。 需要手动替换字符才能浏览的文本体验好
|
105
TomPig0216 2023-06-01 23:25:17 +08:00
不错 很有意思哈哈
|
107
nexo 2023-06-01 23:28:28 +08:00
前端很基础的东西...... 刚好最近在搞在线编辑器 看到这么多人惊讶 只能说网页编辑器领域太冷门了.....
|
109
akira 2023-06-01 23:43:18 +08:00
这玩意。。风险有点大啊。。
|
112
SomethingIsWrong 2023-06-02 00:09:18 +08:00
实话说,前天晚上需要临时复制 json 数据的时候还想过这种应用,没想到今天就有人搞出来了:)
|
113
lei2j 2023-06-02 00:33:16 +08:00 via Android
真会玩
|
114
kuangkuang 2023-06-02 09:38:06 +08:00
不错,临时的文本和图片其实更推荐 ditto ,毕竟有历史记录
|
115
fengqi 2023-06-02 10:04:07 +08:00
6 ,还能这么玩
|
116
southFlowFire 2023-06-02 11:41:13 +08:00 2
为什么我第一反应就是,这个玩法太适合规避审查了。
比如内网有份文档,正常情况发不出去,会被审查拦下,这么一搞审查直接无效,触发不了预警机制了 |
117
linyongqianglal 2023-06-02 12:08:30 +08:00
好活
|
118
meeop OP @southFlowFire 不是挺好的?
|
119
EaStack 2023-06-02 13:22:44 +08:00
便携版:data:text/html,<html contenteditable>hi
|
120
awesomes 2023-06-02 13:43:42 +08:00
说白了就是在你的浏览器中打开一个本地的 html 文件而已,有啥风险,有啥技术,有啥大惊小怪的么,但凡有点前端常识都明白的事
|
121
azui999 2023-06-02 14:10:10 +08:00
挺有趣,收藏了
|
122
googlefans 2023-06-02 15:02:30 +08:00
太牛了..
太有创艺了 |
123
zhw2590582 2023-06-02 17:04:21 +08:00
有点意思
|
124
Leung818 2023-06-02 17:34:28 +08:00
我没啥文化,先来一句卧槽
|
125
kobezone 2023-06-02 18:43:50 +08:00 via Android
真是 NB 这都能想到 妙啊 楼主🐂🍺plus
|
127
mghio 2023-06-02 21:38:49 +08:00
以下是来自 Google Bard 对其工作原理的解释:
The code data:text/html;base64,PGh0bWwgY29udGVudGVkaXRhYmxlPmVkaXQgbWU8L2h0bWw+ in a browser URL is a data URI scheme. It is a way of embedding a small amount of data, such as text, images, or CSS, directly into a web page. This can be useful for things like embedding a small logo or tracking pixel into a page, or for providing fallback content for users who cannot load external resources. The data URI scheme is defined by the following syntax: Code snippet data:[<media type>][;base64],<data> Use code with caution. Learn more The <media type> is a string that identifies the type of data being embedded. The <data> is the actual data, encoded in base64. In the example you provided, the <media type> is text/html and the <data> is the HTML code for a simple page. This page contains a heading and a paragraph of text. When a browser encounters a data URI, it will decode the base64 data and then treat it as if it had been loaded from an external resource. In this case, the browser will load the HTML code and display it as a web page. Data URIs can be a useful way to embed small amounts of data into web pages. However, they should be used sparingly, as they can increase the size of the page and make it slower to load. Here are some additional things to keep in mind when using data URIs: The maximum size of a data URI is 32KB. Data URIs are not supported by all browsers. Data URIs can be used to embed malicious code. If you are considering using data URIs, it is important to weigh the benefits and drawbacks carefully. |
128
fox233 2023-06-03 14:18:58 +08:00
这种链接可以生产二维码吗?还有就是手机端访问字很小,可以适配手机端吗
|
129
Llesue 2023-06-03 16:33:25 +08:00
<!DOCTYPE html>
<html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>小小记事本</title> <style> * { margin: 0 auto; box-sizing: border-box; color: #777777; outline: none; } body { background: #f5f5f5; } .main { display: flex; flex-direction: column; max-width: 960px; } .container { display: flex; width: 100%; margin: 5vh 0 1.5vh; } .title { flex: 1; font-size: 2em; font-weight: 600; padding-left: 16px; white-space: nowrap; } .edit { width: 100%; min-height: 50vh; padding: 16px; font-size: 1.2em; border: 1px dashed #ccc; border-radius: 2px; background: #fff; } button { border: 1px solid #ccc; padding: 0 20px; cursor: pointer; } </style> </head> <body> <div class="main"> <div class="container"> <div class="title" contenteditable>编辑标题✏️</div> <button id="btn">复制当前页 dataUrl</button> </div> <div class="edit" contenteditable>编辑这里开始.✏️</div> </div> <script> function utf8_to_b64(str) { return window.btoa(unescape(encodeURIComponent(str))); } // function b64_to_utf8(str) { // return decodeURIComponent(escape(window.atob(str))); // } const btn = document.querySelector("#btn"); btn.addEventListener("click", () => { const htmlContent = document.querySelector("html"); console.log(htmlContent.innerHTML); const dataUrl = "<html>" + htmlContent.innerHTML + "</html>"; const base64 = utf8_to_b64(dataUrl); // console.log(base64); const inputValue = `data:text/html;base64,${base64}` const input = document.createElement("input"); input.setAttribute("readonly", "readonly"); input.setAttribute("value", inputValue); document.body.appendChild(input); input.setSelectionRange(0, 9999); input.select(); document.execCommand("copy"); document.body.removeChild(input); alert('地址已复制。') }); </script> </body> </html> |
131
Llesue 2023-06-03 17:55:13 +08:00 2
data:text/html;charset=utf-8,<title>小小记事本</title><style>* {margin: 0 auto;box-sizing: border-box;color: gray;outline: none;border-radius: 5px;}</style><script> function copyToClipboard() { var htmlContent = document.documentElement.outerHTML; var tempInput = document.createElement("textarea"); tempInput.style.opacity = 0; tempInput.value = 'data:text/html;charset=utf-8,' +htmlContent; document.body.appendChild(tempInput); tempInput.select(); document.execCommand("copy"); document.body.removeChild(tempInput); alert("已复制"); } </script><body style="background: gainsboro;"><div style="display: flex; flex-direction: column; max-width: 960px;"><div style="display: flex; width: 100%; margin: 5vh 0 1.5vh;"><div style="flex: 1; font-size: 2em; font-weight: 600; padding-left: 16px; white-space: nowrap;" contenteditable>编辑标题✏️</div><button onclick="copyToClipboard()" style="border: 1px solid lightgray; padding: 0 20px; cursor: pointer; font-size: 1em;">复制当前页 dataUrl</button></div><div style="width: 100%; min-height: 50vh; padding: 16px; font-size: 1.2em; border: 1px dashed lightgray; background: whitesmoke; text-align: justify;" contenteditable>编辑这里开始.✏️
会了 |
132
lizhenda 2023-06-03 21:20:51 +08:00
厉害了啊,还可以这么玩
|
134
meeop OP @fox233 网上搜索个二维码生成器就能做二维码了,但我试了下微信扫不会帮你打开链接,只能复制扫出来的内容手动贴浏览器执行。适配手机端的话肯定可以,这就是个标准网页,但需要额外开发下
|
136
xxl123456 2023-06-05 17:19:08 +08:00
有无大佬解释原理是什么
|
139
jixule 2023-06-06 15:07:51 +08:00
@Llesue 试了一下,界面好看多了,有俩问题:1. 如果复制 vscode 内容,编辑区带有格式生成 url ,打开是空白; 2.编辑区如果复制纯文本,遇到 16 进制颜色的#后面就不显示了,标题中有#后面页面全都不显示了
|
140
ixoy 2023-06-06 17:08:43 +08:00 1
|
141
meeop OP @ixoy 不太一样,峰哥这个是在当前页面上下文注入一段 js 代码,更接近于浏览器插件
例如这个链接会 alert 当前页面的标题 javascript:alert(document.title) 不过浏览器限制挺狠的,这个链接不能复制粘贴到地址栏,只能手敲前面的 javascript:,或者编辑书签地址才能使用 不过有意思的点是它能访问当前页面上下文,可以拿来做页面插件和外挂功能 |
142
rookiebulls 2023-06-07 15:28:46 +08:00 1
```
data:text/html;charset=utf-8,<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> </head> <body style="margin: 0; height: 100vh"> <div id="container" style="width: 100%; height: 100%"></div> <script type="text/javascript" src="https://unpkg.com/monaco-editor@latest/min/vs/loader.js"></script> <script> require.config({ paths: { vs: "https://unpkg.com/monaco-editor@latest/min/vs" } }); require(["vs/editor/editor.main"], function () { monaco.editor.create(document.getElementById("container"), { language: "json", theme: "vs-dark", }); }); </script> </body> </html> ``` 给个 vscode 版的 |
143
InkAndBanner 2023-06-08 15:30:48 +08:00
@Cheons #100 怎么规避审查呢?反骨 boy 十分感兴趣,这个记事本原则上不支持保存呀,除非 ctrl+s
|
144
meeop OP @InkAndBanner 比如这样 data:text/html;base64,PCFET0NUWVBFIGh0bWw+CjxoZWFkPgogICAgPG1ldGEgY2hhcnNldD0iVVRGLTgiPgo8L2hlYWQ+CjxodG1sIGNvbnRlbnRlZGl0YWJsZT7ov5nmmK/kuIDmrrXpmZDliLbnuqflhoXlrrk8L2h0bWw+
|
145
xml123 2023-06-25 10:15:16 +08:00
@rookiebulls 这个不能适应浏览器窗口大小的变化,可以改进吗?另外 langugae 只能在地址里设置吗?
|
146
freepoint 2023-07-14 13:56:30 +08:00
@mokevip #61 文本 data:text/html;text,<html contenteditable>edit me</html> 是一段 HTML 代码,它创建了一个可编辑的 HTML 页面。你可以在浏览器中打开这段代码,并编辑页面的内容。
这段代码的具体解释如下: data: 是数据 URI 协议。数据 URI 协议允许你在 HTML 文档中嵌入数据,例如图像、文本或脚本。 text/html 是数据类型。在本例中,数据类型是 HTML 。 text, 是分隔符。它用于分隔数据类型和数据。 <html contenteditable> 是 HTML 代码。这段代码创建了一个 HTML 页面,页面的内容是可编辑的。 edit me 是页面的内容。你可以在浏览器中打开这段代码,并编辑页面的内容。 |
147
shayebushi 2023-07-21 14:24:25 +08:00
每隔 5 秒自动保存到 localstorage
<html contenteditable> <head> <title>Note</title> <script> const contentEditable = document.querySelector('[contenteditable]'); const savedContent = localStorage.getItem('savedContent'); if (savedContent) { contentEditable.innerHTML = savedContent; } setInterval(function() { const content = contentEditable.innerHTML; localStorage.setItem('savedContent', content); }, 5000); </script> </head> <body> </body> </html> |
148
wangxiao20170401 205 天前 1
结合上面大家所发代码优点,可以防关闭、刷新,可设置标题,可复制
------------------------------------------------- data:text/html;charset=utf-8,%3Chtml%3E%3Chead%3E%0A%20%20%20%20%3Ctitle%3E%E4%B9%A6%E7%AD%BE%E8%AE%B0%E4%BA%8B%E6%9C%AC%3C%2Ftitle%3E%0A%20%20%20%20%3Cstyle%3E%0A%20%20%20%20%20%20%20%20body%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20font-family%3A%20Arial%2C%20sans-serif%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20background%3A%20%23f4f4f4%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20margin%3A%200%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20padding%3A%2020px%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20.container%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20max-width%3A%20600px%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20margin%3A%200%20auto%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20padding%3A%2020px%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20background%3A%20%23fff%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20box-shadow%3A%200%200%2010px%20rgba(0%2C%200%2C%200%2C%200.1)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20border-radius%3A%208px%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20.input-group%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20display%3A%20flex%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20margin-bottom%3A%2020px%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%23titleInput%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20flex%3A%201%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20padding%3A%2010px%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20border%3A%201px%20solid%20%23ddd%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20border-radius%3A%204px%200%200%204px%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20font-size%3A%2016px%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20.input-group%20button%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20padding%3A%2010px%2020px%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20border%3A%20none%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20background%3A%20%23007BFF%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20color%3A%20%23fff%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20font-size%3A%2016px%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20cursor%3A%20pointer%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20transition%3A%20background%200.3s%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20.input-group%20button%3Ahover%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20background%3A%20%230056b3%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20.input-group%20button%3Afirst-of-type%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20border-radius%3A%200%204px%204px%200%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20margin-right%3A%2010px%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20.content-editable%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20border%3A%202px%20dashed%20lightgray%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20padding%3A%2010px%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20text-align%3A%20justify%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20min-height%3A%20100px%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20border-radius%3A%204px%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%3C%2Fstyle%3E%0A%20%20%20%20%3Cscript%3E%0A%20%20%20%20%20%20%20%20window.addEventListener(%22beforeunload%22%2C%20function%20(e)%20%7B%20e.preventDefault()%2C%20e.returnValue%20%3D%20%22%22%2C%20alert()%20%7D)%3B%0A%20%20%20%20%20%20%20%20function%20updateTitle()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20document.title%20%3D%20document.getElementById('titleInput').value%3B%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20function%20copyPageContent()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20var%20htmlContent%20%3D%20document.documentElement.outerHTML%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20var%20tempInput%20%3D%20document.createElement(%22textarea%22)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20tempInput.style.opacity%20%3D%200%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20tempInput.value%20%3D%20'data%3Atext%2Fhtml%3Bcharset%3Dutf-8%2C'%20%2B%20encodeURIComponent(htmlContent)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20document.body.appendChild(tempInput)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20tempInput.select()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20document.execCommand(%22copy%22)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20document.body.removeChild(tempInput)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20alert(%22Page%20content%20copied%20as%20data%20URL%22)%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%3C%2Fscript%3E%0A%3C%2Fhead%3E%0A%0A%3Cbody%3E%0A%20%20%20%20%3Cdiv%20class%3D%22container%22%3E%0A%20%20%20%20%20%20%20%20%3Cdiv%20class%3D%22input-group%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cinput%20type%3D%22text%22%20id%3D%22titleInput%22%20placeholder%3D%22Enter%20new%20title%20here%22%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cbutton%20onclick%3D%22updateTitle()%22%3ESet%20Title%3C%2Fbutton%3E%0A%20%20%20%20%20%20%20%20%20%20%20%20%3Cbutton%20onclick%3D%22copyPageContent()%22%3ECopy%3C%2Fbutton%3E%0A%20%20%20%20%20%20%20%20%3C%2Fdiv%3E%0A%20%20%20%20%20%20%20%20%3Cdiv%20class%3D%22content-editable%22%20contenteditable%3D%22%22%3E%3C%2Fdiv%3E%0A%20%20%20%20%3C%2Fdiv%3E%0A%0A%0A%3C%2Fbody%3E%3C%2Fhtml%3E |
149
wangxiao20170401 205 天前 1
data:text/html,<html><head><title>书签记事本</title><style>body{padding:20px}.content-editable{border:1px dashed;margin-top:10px;padding:10px;min-height:100px}</style><script>window.addEventListener("beforeunload",function(e){e.preventDefault(),e.returnValue="",alert()});function updateTitle(){document.title=document.getElementById('titleInput').value}function copyPageContent(){var tempInput=document.createElement("textarea");tempInput.value='data:text/html;charset=utf-8,'+encodeURIComponent(document.documentElement.outerHTML);document.body.appendChild(tempInput);tempInput.select();document.execCommand("copy");document.body.removeChild(tempInput);alert("Page content copied")}</script></head><body><input type="text" id="titleInput" placeholder="Enter new title"><button onclick="updateTitle()">Set Title</button><button onclick="copyPageContent()">Copy</button><div class="content-editable" contenteditable></div></body></html>
上面的太笨重了,精简了下 |
150
meeop OP @所有人 我做了一个聚合这类 app 的网站,参考 https://www.v2ex.com/t/1059349?p=1#reply38
|