使用Javascript将HTML本地保存

34

我知道客户端的JavaScript由于明显的安全原因无法将数据写入本地文件系统。

似乎使用cookie、localStorage或允许用户下载文件(通过"保存..."对话框或浏览器默认下载文件夹)是JavaScript保存数据到本地的唯一方式。

但是,在特定情况下,当文件通过类似file:///D:/test/index.html这样的本地URL进行访问时(而不是通过Internet),是否有可能在本地浏览HTML文件时写入数据?(不需要任何服务器语言,甚至没有任何服务器:只是本地浏览HTML文件)

例如,点击这里的保存按钮,是否可能:

  <div contenteditable="true" style="height:200px;">Content editable - edit me and save!</div>
  <button>Save</button>

如何才能使HTML文件(通过file:///D:/test/index.html访问)被其新内容覆盖?(即在按下SAVE时应更新本地HTML文件)。


enter image description here


TL;DR:当通过本地方式访问HTML页面时,是否可能通过Javascript保存文件?

注:我想要能够静默保存,而不是提供一个下载/保存对话框,在该对话框中,用户必须选择下载位置,然后出现"您确定要覆盖吗"等提示。


编辑:为什么问这个问题?因为我正在制作一个浏览器内记事本,可以在本地运行,无需任何服务器(没有Apache,没有PHP)。我需要能够轻松保存,而无需处理“在哪里下载文件?”对话框,并且总是重新浏览到同一文件夹以覆盖当前正在编辑的文件。我希望有一个简单的UX,就像任何记事本程序一样:CTRL+S完成,当前文件已保存!(例如:MS Word不会在每次执行“保存”操作时都要求浏览文件保存位置:CTRL+S完成!)


2
我相信你唯一能做到的方法就是将内容提交给某些服务器端处理(例如PHP,Python等),并让本地脚本更新文件。 - Jacob Ewing
1
@JacobEwing 而且没有服务器端处理?我的意思是本地浏览HTML文件,即浏览器打开c:\myproject\index.html,没有Apache服务器/没有PHP服务器。 - Basj
1
如果您在浏览器中执行脚本(即使从本地计算机加载),那么就无法告诉它修改本地文件(这是浏览器防止这种情况发生,而不是服务器)。您可能可以使用其他软件来执行它,在这种情况下,我不知道还有什么限制。https://dev59.com/qnA85IYBdhLWcg3wF_m0 中有一些更多的信息可能会有所帮助。 - Jacob Ewing
1
@Basj:关于node-webkit,它可以生成可在终端机上运行而无需安装node-webkit本身的程序。HTA适用于Windows系统,并且您可以使用FSO读写文件,只要文件有一个<APPLICATION>标签即可。还有Chrome打包应用和Firefox应用,以及Cordova。 - dandavis
1
@kzaiwo 我刚刚发起了一个悬赏,看看是否有新的方法。 - Basj
显示剩余16条评论
13个回答

0

我认为在这个背景下澄清服务器和客户端之间的区别非常重要。

客户端/服务器是一种程序关系,其中一个程序(客户端)请求另一个程序(服务器)提供服务或资源。

来源:http://searchnetworking.techtarget.com/definition/client-server

我不确定你是否能找到没有至少一个服务器/客户端关系的高级应用程序。如果没有任何服务器实现这一点有些误导,因为每当你的程序与另一个程序交互时,它就是一个客户端/服务器关系,请求者是客户端,响应来自服务器。即使你是在本地工作。当你想做一些超出浏览器范围的事情时,你需要在服务器上挂钩。

现在,这并不意味着您不能在没有服务器端特定语言的情况下实现此目标。例如,this solution 使用NodeJS作为服务器。WinJS具有WinJS.xhr,它使用XmlHttpRequest将数据提供给服务器。

AJAX旨在提供相同类型的功能。关键在于,无论您是否拥有程序或已经构建了某种钩子,当您发出像“保存文件”这样的命令并且文件实际上被保存时,另一侧有一个程序正在解析它,无论是服务器端语言还是其他东西,这意味着您不可能在没有服务器接收请求的情况下拥有此类函数。


0

0

这是一个示例,供那些想要了解如何使用localStorage的人参考。

<div id="divInput" contenteditable="true" style="height:200px;border: 2px solid blue">
  Content editable - edit me and save!
</div>
<button onclick="onSave()">Save</button>
<button onclick="onLoad()">Load</button>
<script>
  config = {
    localStorageItemName: "demo",
    datetimeFormat: {
      year: 'numeric',
      month: '2-digit',
      day: '2-digit',
      hour: '2-digit',
      hour12: false,
      minute: '2-digit',
      second: '2-digit'
    }
  }

  function Now() {
    return new Date().toLocaleString("zh-TW", config.datetimeFormat)
  }

  const errMap = {
    IsEmptyError: new Error('is empty'),
    LengthError: new Error('length = 0')
  }

  /**
   * @param {string} itemName
   * @return {Object}
   * */
  function getLocalStorageItem(itemName) {
    const dbDataString = localStorage.getItem(itemName)
    if (dbDataString === null) {
      throw errMap.IsEmptyError
    }
    const db = JSON.parse(dbDataString)
    if (Object.keys(db).length === 0) {
      throw errMap.LengthError
    }
    return db
  }

  function onSave() {
    const inputValue = document.querySelector(`#divInput`).textContent
    try {
      const db = getLocalStorageItem(config.localStorageItemName)
      db.msg = inputValue
      db.lastModTime = Now()
      localStorage.setItem(config.localStorageItemName, JSON.stringify(db))
      console.log("save OK!")
    } catch (err) {
      switch (err) {
        case errMap.IsEmptyError:
          console.info("new localStorageItemName")
          localStorage.setItem(config.localStorageItemName,
            JSON.stringify({msg: inputValue, createTime: Now()})
          )
          break
        /*
        case ...
          break
        */
        default:
          console.error(err.message)
      }
    }
  }

  function onLoad(e) {
    try {
      const db = getLocalStorageItem(config.localStorageItemName)
      console.log("load")
      document.querySelector(`#divInput`).textContent = db.msg
    } catch (err) {
      return
    }
  }
  (()=>{
    window.onload = () => (
      onLoad()
    )
  })()
</script>

它是用纯JavaScript编写的,没有依赖关系。

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接