我在 jsp 中使用jsp和servlet,方法类型为 POST 。但是在插入记录后再次刷新页面创建新记录。任何人都可以帮助我在 php 中使用替代标题吗?
或任何其他解决方案,我尝试了很多,但我的问题没有解决,所以再次发布这个问题。
谢谢
假设有 3 页
(1) Registration.jsp :具有注册表<form action="AddUser.jsp" >,用户可以在其中输入数据。
(2) AddUser.jsp(或者更好的是servlet):接受“Registration.jsp”提交的数据。
(3) Welcome.jsp : 注册后会出现这个页面。
所以在page2(AddUser.jsp)中写下如下代码
由于浏览器 URL 将被更改。因此,如果用户刷新页面,那么它也不会创建重复的条目。
如果我理解你的话:
POST /insertdata到www.mypage.comOK 200 您可以通过这样的重定向来避免它:
response.sendRedirect("http://www.mypage.com/insertsuccessful");
将此代码放在处理 POST 的 servlet/JSP 的末尾。这将发生:
POST /insertdata到www.mypage.comMOVED_TEMPORARILY 302以标头响应Location: http://www.mypage.com/insertsuccesful GET /insertsuccesful到www.mypage.com注意:状态码 (302) 和位置标头由该sendRedirect方法自动设置。
现在,当用户刷新页面时,它将不再发布重复数据。www.mypage.com/insertsuccesful
www.mypage.com/insertfailed如果您在 POST 处理程序中捕获异常,您还可以创建页面并重定向到它。
更新 2
为了跟进@JB Nizet 的评论(感谢您的小心),我们假设您的 web 应用程序使用上下文路径部署,例如www.mypage.com/webapp,并查看以下场景:
http://www.mypage.com/webapp/insertdata?redirectOnOK=/insertsuccessful) 包含一个查询字符串参数redirectOnOk,该参数定义成功插入后客户端将重定向到的位置 ->http://www.mypage.com/webapp/insertsuccessful首先要注意的是这http://www.mypage.com/webapp/insertdata?redirectOnOK=/insertsuccessful不是一个有效的 URL。这是无效的,因为您不希望/在问号 ( ) 后出现斜线 ( ?):
scheme://domain:port/path?query_string#fragment_id
有效的 URL 可以包含英文字母、数字、点 ( .)、连字符 ( -)、下划线 ( _) 和波浪号 ( ~)。其他一些标点符号是保留的,并且每个其他字符(有时甚至是保留字符)都必须是URL 编码的:
http://www.mypage.com/webapp/insertdata?redirectOnOK=%2Finsertsuccessful
由于在保留/字符问号 ( ?) 之后不需要保留字符斜线 ( ),因此必须对其进行编码。这是第一种情况的解决方案:
String redirectRelativeUrl = new URLDecoder().decode(request.getParameter("redirectOnOk"),"UTF-8");
response.sendRedirect(request.getContextPath() + redirectRelativeUrl)
URLDecoder#decode解码%2F为/HttpServletRequest#getContextPath需要返回 /webapp(在第一种情况下,它会返回一个空字符串,因为没有上下文路径)/webapp/insertsuccessful进入sendRedirect方法/webapp/insertsuccessful如果您在形成查询字符串时使用非英文字母字符,则键和值应始终为URL 编码:
String safe = new UrlEncoder().encode("ž@Š","UTF-8");
URL 重写是一种基于正则表达式映射 URL 的机制。换句话说,浏览器请求:
http://www.mypage.com/webapp/resource/someName/12
如果上下文根目录下有一个 JSP 页面resource.jsp,那么可以定义一个 URL 重写规则来将上面的内容映射到:
http://www.mypage.com/webapp/resource.jsp?name=someName&count=12
因此,如果您以编程方式从您的 serlvet/JSP 重定向,您还必须应用(出站)URL 重写规则。在上面的示例中,入站规则是:
/someName/12->?name=someName&count=12 /webapp/resource->/webapp/resource.jsp从服务器以编程方式重定向时需要应用出站规则:
name=someName&count=12->/someName/12 /resource.jsp->/resource为了简单起见,规则以这种方式呈现,实际上并不是正则表达式。这种情况下的解决方案是:
response.sendRedirect(response.encodeRedirectURL(request.getRequestURI() + "?" + request.getQueryString())
getRequestURI返回/webapp/resource.jspgetQueryString返回name=someName&count=12encodeRedirectURL有输入/webapp/resource.jsp?name=someName&count=12/webapp/resource/someName/12Session session = request.getSession();
这样做的结果是它设置了一个JSESSIONID cookie:
jsessionid=9ADABC18DB58C4DA99896C6261D2DD25
如果浏览器禁用了 cookie,则在程序化重定向时,用户将不再被验证,这意味着他将不得不再次登录。这种情况下的解决方案是:
String relativeRedirectUrl="/insertSucessful";
response.sendRedirect(response.encodeURL(request.getContextPath() + relativeRedirectUrl));
encodeURL如果 cookie 被禁用,则附加;jsessionid=9ADABC18DB58C4DA99896C6261D2DD25到输入/webapp/insertSucessful;jsessionid=9ADABC18DB58C4DA99896C6261D2DD25我认为您已经通过“linski”和“Rakesh”详细说明了答案的最重要部分。为此,我对他们都投了赞成票。
然而,我想指出一件事。
两个答案中都提到了已经存在一段时间的 PRG(Post-Redirect-Get)模式。这将解决大多数重复发布问题,但失败的一个领域是存在“服务器滞后”。如果您的后端工作在启动重定向之前有一些明显的滞后时间,则用户可能会通过再次单击提交按钮(假设您正在使用发布数据的按钮)来启动多个发布操作。
一个简单的前端解决方案是在第一次单击后暂时禁用按钮(或您用来启动发布操作的任何按钮)。
您当然可以在后端发挥创意,以确保同一用户在重定向发生之前不会发布重复的帖子,但这需要更多的工作。