在新标签/窗口中打开/下载文件时,刷新/浏览当前页面 [英] Refresh/navigate current page while opening/downloading file in new tab/window

查看:182
本文介绍了在新标签/窗口中打开/下载文件时,刷新/浏览当前页面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个按钮,打开一个新的标签与生成的pdf文件。
但是,点击按钮后,我想导航到另一个页面。



这意味着,点击按钮后,我想用PDF打开一个新的标签页,并在初始选项卡上导航到另一个页面。我使用的是 p:commandButton 并尝试使用 onclick =window.location.href ='www.google.de'但它不工作。但是, onclick =window.lalert('www.google.de')可以正常工作。



我的代码:

 < h:form id =transFormtarget =_ blank> 
< p:commandButton value =Zertifikat erstellenajax =false
label =Speichert die Anmeldung und erstellt ein Zertifikat im PDF格式
action =#{transportErfassen。 generatePDFZertifikat()}/>

< / h:form>

generatePDFZertifikat()文件具有以下代码,我认为这是一个问题:

  FacesContext facesContext = FacesContext.getCurrentInstance(); 
ExternalContext externalContext = facesContext.getExternalContext();

externalContext.setResponseContentType(application / pdf);
externalContext.setResponseHeader(Expires,0);
externalContext.setResponseHeader(Cache-Control,must-revalidate,post-check = 0,pre-check = 0);
externalContext.setResponseHeader(Pragma,public);
externalContext.setResponseHeader(Content-disposition,inline; filename = \+ fileName +\);
externalContext.setResponseContentLength(out.length);
externalContext.addResponseCookie(Constants.DOWNLOAD_COOKIE,true,new HashMap< String,Object>());

// setze explizit auf OK
externalContext.setResponseStatus(200);

OutputStream os = externalContext.getResponseOutputStream();
os.write(out,0,out.length);
os.flush();

facesContext.responseComplete();
facesContext.renderResponse();


解决方案

您基本上是尝试发送2条回复1个请求。这不会在HTTP中工作。如果你想发送2个回复,你必须让客户端以不同的方式发送2个请求。您已经在正确的方向找到解决方案,几乎没有JavaScript的帮助,可以在单个事件上触发多个请求(单击)。您在 onclick 中的尝试无效,之前更改了 window.location ,点击提交按钮表单提交,完全中止按钮的原始动作,提交表单。



您最好的选择是直接导航到结果页面,从而调用JavaScript window.open()页面加载,指向您要打开的PDF文件的URL。这是不可能发送一些HTML / JS代码与PDF文件指示导航(这显然会损坏PDF文件)。这也意味着您不能将PDF直接返回到表单提交请求。代码必须重新设计,以便可以通过后续GET请求检索PDF。最好的方法是使用一个简单的servlet。您可以将生成的PDF临时存储在与唯一密钥相关联的磁盘或会话中,并将该唯一密钥作为请求路径信息或参数传递到 window.open() URL



这是一个开球示例:



初始形式:

 < h:form> 
...
< p:commandButton ... action =#{bean.submit}/>
< / h:form>

Bean:

 this.filename = file.getName(); 

//向其写入内容

returntargetview;
}

目标视图:



< pre class =lang-html prettyprint-override> < h:outputScript rendered =#{not empty bean.filename}>
window.open('#{request.contextPath} / pdfservlet /#{bean.filename}');
< / h:outputScript>

PDF servlet(为简洁起见,省略了nullchecks等等; Java 7假定为文件# copy()):

  @WebServlet(/ pdfservlet / *)
public class PdfServlet extends HttpServlet {

protected void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException,IOException {
File file = new File(/ path / to / pdfs 。getPathInfo()子串(1));
response.setHeader(Content-Type,application / pdf);
response.setHeader(Content-Length,String.valueOf(file.length()));
response.setHeader(Content-Disposition,inline; filename = \zertifikat.pdf\);
Files.copy(file.toPath(),response.getOutputStream());
}

}


I have a button which opens a new tab with a generated pdf-file. However, after I click on the button, I want to navigate to another page.

That means, after clicking on the button i want to open a new tab with the pdf and navigate to another page on the initial tab. I am using primefaces p:commandButton and tried with onclick="window.location.href='www.google.de'" but it does not work. However onclick="window.lalert('www.google.de')" does work.

This is my code:

<h:form id="transForm" target="_blank">
<p:commandButton  value="Zertifikat erstellen" ajax="false" 
                                label="Speichert die Anmeldung und erstellt ein Zertifikat im PDF-Format"
                                action="#{transportErfassen.generatePDFZertifikat()}"/>

</h:form>

generatePDFZertifikat() does create a pdf-File with following code, I think here is the issue:

    FacesContext facesContext = FacesContext.getCurrentInstance();
    ExternalContext externalContext = facesContext.getExternalContext();

    externalContext.setResponseContentType("application/pdf" );
    externalContext.setResponseHeader("Expires", "0");
    externalContext.setResponseHeader("Cache-Control","must-revalidate, post-check=0, pre-check=0");
    externalContext.setResponseHeader("Pragma", "public");
    externalContext.setResponseHeader("Content-disposition", "inline; filename=\"" + fileName +"\"");
    externalContext.setResponseContentLength(out.length);
    externalContext.addResponseCookie(Constants.DOWNLOAD_COOKIE, "true", new HashMap<String, Object>());

    //setze explizit auf OK
    externalContext.setResponseStatus(200);     

    OutputStream os = externalContext.getResponseOutputStream();
    os.write(out, 0, out.length);
    os.flush();

    facesContext.responseComplete();       
    facesContext.renderResponse();       

解决方案

You're basically trying to send 2 responses back to 1 request. This is not ever going to work in HTTP. If you want to send 2 responses back, you've got to let the client fire 2 requests somehow. You were already looking in the right direction for the solution, with little help of JavaScript it's possible to fire multiple requests on a single event (click). Your attempt in onclick is however not valid, the change of window.location on click of the submit button, right before the form submit, completely aborts the original action of the button, submitting the form.

Your best bet is to directly navigate to the result page which in turn invokes JavaScript window.open() on page load, pointing to the URL of the PDF file which you'd like to open. It's namely not possible to send some HTML/JS code along with the PDF file instructing a navigation (as that would obviously corrupt the PDF file). This also means, that you can't return the PDF directly to the form submit request. The code has to be redesigned in such way that the PDF can be retrieved by a subsequent GET request. The best way is to use a simple servlet. You could store the generated PDF temporarily on disk or in session, associated with an unique key, and pass that unique key as request pathinfo or parameter to the servlet in window.open() URL.

Here's a kickoff example:

Initial form:

<h:form>
    ...
    <p:commandButton ... action="#{bean.submit}" />
</h:form>

Bean:

public String submit() {
    File file = File.createTempFile("zertifikat", ".pdf", "/path/to/pdfs");
    this.filename = file.getName();

    // Write content to it.

    return "targetview";
}

Target view:

<h:outputScript rendered="#{not empty bean.filename}">
    window.open('#{request.contextPath}/pdfservlet/#{bean.filename}');
</h:outputScript>

PDF servlet (nullchecks etc omitted for brevity; Java 7 assumed for Files#copy()):

@WebServlet("/pdfservlet/*")
public class PdfServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        File file = new File("/path/to/pdfs", request.getPathInfo().substring(1));
        response.setHeader("Content-Type", "application/pdf");
        response.setHeader("Content-Length", String.valueOf(file.length()));
        response.setHeader("Content-Disposition", "inline; filename=\"zertifikat.pdf\"");
        Files.copy(file.toPath(), response.getOutputStream());
    }

}

这篇关于在新标签/窗口中打开/下载文件时,刷新/浏览当前页面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆