我有一个表单,允许用户选择检查,并在提交时创建一个PDF,该PDF在新的浏览器选项卡中打开。它没有任何品牌,并且可能会在插件中打开,所以我不希望它接管我的网站选项卡。所以我将表单target
设置为_blank
。
但是用户可以在没有足够信息的情况下提交表单来创建PDF,在这种情况下,我会标记错误(服务器端)并重新呈现表单。但是因为我设置了表单的目标,所以这个重新渲染也会在新标签页中打开,而不是我想要的东西 - 在这种情况下,我希望它的行为就好像target
是_top
。
所以问题是:我可以更改浏览器的渲染目标服务器端吗?
是的,我知道这可以通过客户端JavaScript来完成,但JS让我很烦,而且我还是要做验证服务器端。我可能最终不得不使用它,但请不要将它作为答案 - 如果我正在尝试甚至可以做的话,我会更好奇。
PS:我使用Ruby on Rails 2.3.8,以防有人知道特定于框架的解决方案。
答案 0 :(得分:1)
解决这个问题的方法是使用pdf上的content-disposition标头,以强制下载文件,并避免整个“目标”方法..
Content-type: application/pdf
Content-Disposition: attachment; filename="downloaded.pdf"
答案 1 :(得分:0)
没有。这是一个纯粹的客户端特定功能。事实上,很有可能得到一个只支持一个窗口的浏览器,而target
属性根本没有效果。甚至还有努力使这个属性完全从未来的HTML标准中消失(例如,XHTML分支没有这样的属性)。
我可以在HTML和HTTP之间考虑的唯一重叠是<meta http-equiv>
标记(其中HTML可以影响HTTP控制的行为)。 HTTP是一种传输协议,旨在处理任何类型的数据。让它控制演示将是一个非常糟糕的关注点。
幸运的是,我们生活在一个支持JavaScript的世界中。使用AJAX请求验证表单相当容易,特别是对于像jQuery这样的库。
例如,此脚本对URL执行POST请求(在本例中为/pdf/validate
),并期望页面发回“ok”(如果一切正常)或其他内容(如果有错误)。
<form method="post" action="/pdf/send" id="pdf-form">
<!-- form stuff here -->
</form>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
$(document).ready(function()
{
// set to true if we are to bypass the check
// this will happen once we've confirmed the parameters are okay
var programmaticSubmit = false;
// attach an event handler for when the form is submitted
// this allows us to perform our own checks beforehand; we'll do so by
// cancelling the event the user triggered, and do the submit ourselves if
// we detect no error
$('#pdf-form').submit(function(event)
{
if (!programmaticSubmit)
{
// first off, cancel the event
event.preventDefault();
// do an AJAX request to /pdf/validate
$.ajax("/pdf/validate", {
type: "POST",
data: $(this).serialize(), // send the form data as POST data
success: function(result)
{
// this gets called if the HTTP request did not end
// abnormally (i.e. no 4xx or 5xx status);
// you may also want to specify an "error" function to
// handle such cases
if (result == "ok")
{
// since the server says the data is okay, we trigger
// the event again by ourselves, but bypassing the
// checks this time
programmaticSubmit = true;
$(this).submit();
}
else // something went wrong! somehow display the error
alert(result);
}
});
}
});
});
</script>