问候,
我正在研究一个基于JS的应用程序,该应用程序执行一些复杂的工作并在<div>
上记录一些信息(实际上,最多数百行)。
我的目标是有一个“保存日志”按钮,触发浏览器的下载对话框以保存我的日志<div>
的内容。
更简洁地说,这些是此功能的要求:
text/plain
,因此浏览器可以建议默认操作(如“在记事本上打开”),就像正常的文件下载一样。这可以被视为第一个要求的一个具体方面。<div>
的内容复制粘贴到文本编辑器中并将其保存在那里绝对是可怕的,这正是我为什么要避免的原因。我一直在这个网站上搜索,在WHATWG和W3C网站上以及在网上搜索都没有成功。这可行吗?
我最接近的是使用data:
网址。我的第一次尝试,执行POST操作,无法获得内容类型,所以它会回到UA的启发式。通过将<a>
链接设置为看起来像一个按钮并给它一个type
属性,我稍微好了一点,但是然后UA会发挥太聪明并呈现内容而不是保存(并询问用户)在该步骤中从浏览器保存文件变得比采用复制粘贴方法更糟糕,因为浏览器之间的页面保存变化很大。)
如果只有某种方法可以将data:
网址与“内容处理”类型的提示相结合,那么事情就会非常顺利。
此致 Herenvardo
答案 0 :(得分:2)
不幸的是,这不是普通浏览器功能所能做到的。像flash或特定浏览器这样的插件可以满足您的需求,但javascript中的安全限制不允许您下载在浏览器中创建的任意数据。
此外,所有浏览器/版本组合均不支持“数据”网址。我不确定您的用户是否受限于他们使用的是什么浏览器,但这可能会限制您可以使用该解决方案执行的操作。
答案 1 :(得分:2)
这个解决方案有点令人费解,但可以满足您的需求,也许这是一个选择。
创建一个自定义Web服务器,它只返回任何GET或POST的内容为text / plain。
将Web服务器托管在与Web应用程序相同的框中,但在不同的端口上运行。单击“保存日志”按钮时,请求将发送到自定义服务器并返回文本文件。
以下是Java中的概念服务器证明:
// After running this program, access with your browser at 127.0.0.1:8080
import java.net.*;
import java.io.*;
public class ReturnTextFile
{
public static void main(String[] args)
{
try
{
ServerSocket server = new ServerSocket(8080);
Socket connection = null;
while (true)
{
try
{
connection = server.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String input = in.readLine();
// TODO: Clean up input
Writer out = new OutputStreamWriter(connection.getOutputStream());
String output = "HTTP/1.1 200 OK\n" +
"Connection: close\n" +
"Content-Disposition: attachment; filename=log.txt\n" +
"Content-Type: text/plain; charset=utf-8\n" +
"\n";
output += input;
out.write(output);
out.flush();
connection.close();
}
catch (IOException ex)
{
ex.printStackTrace();
}
finally
{
if (connection != null)
{
connection.close();
}
}
}
}
catch (IOException ex)
{
ex.printStackTrace();
}
}
}
答案 2 :(得分:2)
您可以在data:
网址中设置内容类型,如下所示:
data:text/plain,this is some text
但是,仍然存在浏览器自动将其呈现为文本的问题。你真的有两个我可以看到的选择。一种是您将类型设置为某种二进制类型,以便浏览器不会尝试渲染它,或者您将类型设置为text / plain并让用户右键单击并另存为。也许here可以提供帮助吗?
答案 3 :(得分:1)
我一直走在这条路上,我也想纯粹在客户端做这件事。但是,这是不可能的。您可以毫不费力地触发保存对话框的唯一方法是发出HTTP POST请求,并让服务器使用content-disposition
标头进行响应。
我在my dusty old blog的代码段中拥有您想要的功能。我有一个表单,其中一个隐藏字段指向自定义HTTP处理程序。 Javascript抓取代码块的内部文本,将其放在隐藏字段中,然后提交表单。服务器响应请求的整个主体以及所需的标头。没有刷新,你点击它,你会得到一个保存对话框。效果很棒!