Open Topppy opened 1 year ago
最近发现drawio的一些功能很黑魔法。 比如首次创建一个文件,浏览器系统弹窗保存到本地,(到这为止都是常规保存文件的套路,很好实现)。 接下来,你在浏览器中继续绘制编辑你创建的图表,ctrol+S 保存之后,神奇的事情发生了,没有任何系统弹窗,最新的内容已经被静默地写入了首次创建的文件中。
这个行为是有点反直觉的,相当于在无感知的情况下,直接读写系统文件。浏览器一般不会给这么大的权限。
如果有,也只能是浏览器提供的能力,于是,找到了这个 API: FileSystemWritableFileStream
API: FileSystemWritableFileStream
https://developer.mozilla.org/en-US/docs/Web/API/FileSystemWritableFileStream
<!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>file save</title> <style> #addText { width: 400px; height: 200px; } </style> </head> <body> <h1>保存为本地文件并持续实时保存最新编辑的内容</h1> <h4>text to save:</h4> <div> <textarea id="addText" name="addText">hello</textarea> </div> <button onclick="saveFile()">1. start save</button> <button onclick="updateFile()">2. update</button> <h4>file contents:</h4> <p id="fileContent"></p> <script> // https://developer.mozilla.org/en-US/docs/Web/API/FileSystemWritableFileStream let $textToAdd; let $fileContent; let newHandle; const pickerOpts = { types: [ { description: "Text file", accept: { "text/plain": [".txt"], }, }, ], suggestedName: "testFile", excludeAcceptAllOption: true, multiple: false, }; async function saveFile() { // create a new handle console.log("showSaveFilePicker"); newHandle = await window.showSaveFilePicker(pickerOpts); console.log("createWritable"); // create a FileSystemWritableFileStream to write to const writableStream = await newHandle.createWritable(); updateFile(); } async function getFileContents() { const fileData = await newHandle.getFile(); const res = await fileData.text(); console.log("fileText: ", res); $fileContent.innerText = res; } async function updateFileContent(text) { // create a FileSystemWritableFileStream to write to const writableStream = await newHandle.createWritable(); const data = new Blob([text], { type: "text" }); // write our file await writableStream.write(data); // close the file and write the contents to disk. await writableStream.close(); } async function updateFile() { const text = $textToAdd.value; await updateFileContent(text); await getFileContents(); } document.addEventListener("DOMContentLoaded", () => { $textToAdd = document.getElementById("addText"); $fileContent = document.getElementById("fileContent"); }); </script> </body> </html>
比如前端通过js改写下载文件的内容。
可以继续研究一下这个API有什么安全限制。
https://juejin.cn/post/7086054628294557733
背景:
最近发现drawio的一些功能很黑魔法。 比如首次创建一个文件,浏览器系统弹窗保存到本地,(到这为止都是常规保存文件的套路,很好实现)。 接下来,你在浏览器中继续绘制编辑你创建的图表,ctrol+S 保存之后,神奇的事情发生了,没有任何系统弹窗,最新的内容已经被静默地写入了首次创建的文件中。
这个行为是有点反直觉的,相当于在无感知的情况下,直接读写系统文件。浏览器一般不会给这么大的权限。
如何实现
如果有,也只能是浏览器提供的能力,于是,找到了这个
API: FileSystemWritableFileStream
https://developer.mozilla.org/en-US/docs/Web/API/FileSystemWritableFileStream
兼容性很不好:
思路:
代码: