【问题标题】:Page Expired issue on IE with multipart/form-data form具有多部分/表单数据表单的 IE 页面过期问题
【发布时间】:2014-02-14 13:30:17
【问题描述】:

如果我在表单标签中指定enctype="multipart/form-data",我会在 IE 上遇到“页面已过期”问题。

通过简化,我有 3 个 JSP 页面 page1.jsppage2.jsppage3.jsp

page1.jsp(包含带有enctype="multipart/form-data" 的表单)提交给page2.jsppage2.jsp 提交给page3.jsp

如果我:

  1. 提交到 page2.jsp
  2. 从page2.jsp再次提交到page3.jsp
  3. 从 page3.jsp 返回到 page2.jsp(使用 history.back() javascript),我得到“页面已过期”。

我阅读了关于缓存控制的信息,但是将这些页面设置为私有或公共缓存控制并不会改变这种情况

// page1.jsp
<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<html>
<head>
</head>
<body>
   <form method="post" enctype="multipart/form-data" action="page2.jsp">
File to upload: <input type=file name=upfile>
<input type=submit value="Go to page2"> 
</form> 

 // page2.jsp
<html>
<head>  
</head>
<body>
   <form method="post" action="page3.jsp">            
   <input type=submit value="Go to page3"> 
   </form> 
 </body>
</html>


// page3.jsp
<html>
<head>
</head>
<body>
    <form method="post" action="end.jsp">
    <input type="button" value="Go to page 2" onclick="javascript:history.back();"> 
    <input type=submit value="Go to end">        
    </form>
</body>
</html> 

【问题讨论】:

    标签: internet-explorer jsp file-upload back-button multipartform-data


    【解决方案1】:

    只需使用 post-redirect-get 范例:

    1. page1 -- post --> servlet1
    2. servlet1 -- 处理数据然后重定向 --> page2
    3. page2 -- post --> servlet2
    4. servlet2 -- 处理数据然后重定向 --> page3

    这样,浏览器不会要求重新提交或在后按时显示“页面过期”

    但是您可以减少以这种方式实现的页面/servlet 的数量:

    page2.jsp

    <% 
        if("POST".equals(request.getMethod()) 
        {
            // process submitted params/files
            response.sendRedirect(request.getRequestURI()); // redirect to the same page
        }
    %>
    <html>
        blah blah blah
    </html>
    

    或者你可以简单地使用 ajax。

    【讨论】:

      【解决方案2】:

      而不是在第 2 页上单击以转到第 3 页,您应该使用

      <%
        response.sendRedirect("page3.jsp");
        return;
      %>
      

      上传处理完成后,在 JSP 的第 2 页上。

      当您从第 3 页返回到第 2 页时,您会收到“页面已过期”消息,这是您不应该做也不允许做的事情。如果 page2 是处理文件上传的代码,您必须从那里进行重定向,这将阻止能够使用后退按钮返回到第 2 页。

      为什么要这样做?因为在服务器上执行更新操作(数据库更新、文件上传处理)的页面应该总是重定向到另一个页面,以防止返回按钮重复提交或刷新重复提交问题。 (进行重定向意味着,返回按钮会将您带回到第 1 页而不是第 2 页。第 2 页将在历史记录中被跳过。)

      浏览器本身通过使上传处理页面过期来为您提供一定程度的防止双重文件上传的保护,但您不应该依赖它,因为浏览器不会对正常的表单提交执行此操作,仅适用于文件上传(即多部分/表单数据)。

      【讨论】:

      • 首先文件上传在page1。在这里,我正在简化:在第 1 页上,我有一个带有一些字段(和文件上传)的表单,在第 2 页上,我有另一个带有一些字段(没有文件上传)的表单,在第 3 页上,我有一个用户摘要数据输入,当用户提交 page3 表单时,执行插入并重定向到另一个页面以防止表单重新提交
      • 仍然,您需要在处理上传的页面上进行服务器端重定向,因此您需要超过 3 个页面,然后需要 4 个(或更多)
      • "首先文件上传在 page1" 你的意思是它的表单在 page1 但它在 page2 上处理,对吗?那就是问题所在。 Page2 处理完上传后需要做一次服务端重定向。
      • 是的。当用户在 page1 上提交表单时,servlet 将文件加载到临时目录中并显示 page2。然后用户在 page2 上提交表单,调用第二个 servlet 并显示 page3。问题从第 3 页回到第 2 页(仅在 IE 上)
      【解决方案3】:

      基本上你得到的是正确的。当您返回 page2 时,数据将被重新提交,并且由于没有发生这种情况,因此页面显示为过期。您可以使用其他一些浏览器(例如 Firefox 或 Google Chrome)检查此行为,它会询问您是否要重新提交数据。

      如果您想在 page3 之后到达 page2,则需要从 page3 重定向到 page2,而不是使用历史记录操作返回。

      【讨论】:

      • Firefox 和 Chrome 不会发生这种情况。而且,page1没有上传文件,IE也不会这样。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-11-19
      • 1970-01-01
      • 2020-05-18
      • 2018-12-06
      • 1970-01-01
      • 2012-10-11
      • 2013-03-06
      相关资源
      最近更新 更多