调用客户端重定向后,会话属性将丢失
以前,servlet使用response.sendRedirect("pages/my_page.jsp?foo=bar");
没有问题。 可以在重定向到的后续页面中检索会话属性。
目前,我正在改变发送请求的方式。 最初,Javascript使用myForm.submit();
,但我现在已将其更改为jQuery.ajax("my_page.jsp?foo=bar", {...});
。 然后,servlet包含JSON响应中的URL而不是response.sendRedirect()
,并且在success
函数中,我使用window.location.replace(url);
导航到新页面。 但是,无法在后续页面中获取已保存的会话属性。
我通过在JSP页面中插入来比较会话ID。 他们是一样的。 这里的问题是
session.getAttribute("myAttribute_1")
在重定向到的页面中返回null
。
我不确定这是否重要,但我实际上是在使用多个JSP页面执行此任务:
A.jsp --- (redirect) ---> B.jsp --- (redirect) ---> C.jsp
在这种情况下,如何在C.jsp
获取保存的会话属性?
编辑
下面是我用来保存会话属性的代码片段。
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { HttpSession session = request.getSession(true); response.setContentType("application/json"); CustomObject customObject = new CustomObject(); // ... session.setAttribute("myAttribute_1", customObject); PrintWriter writer = response.getWriter(); JsonObject json = new JsonObject(); Gson gson = new GsonBuilder().setPrettyPrinting().create(); json.addProperty("url", "next_page.jsp?foo=bar"); writer.println(gson.toJson(json)); writer.close(); }
以下是重定向的代码段。
function redirectHandler(data, currentUrl) { if (data && data.hasOwnProperty('url')) { var redirectUrl = data.url; jQuery.get(redirectUrl).done(function(response) { redirectHandler(response, redirectUrl); }); } else { window.location.replace(currentUrl); } } function sendFormData(method, url, form) { jQuery.ajax(url, { 'method': method, 'data': parseData(jQuery(form).serializeArray()), 'success': function(data) { redirectHandler(data, window.location.href); } }); }
结果
我已经恢复使用我的servlet中的response.sendRedirect("pages/my_page.jsp?foo=bar")
。
在客户端, jQuery.ajax()
被删除,函数sendFormData()
更新如下。
function sendFormData(form) { var data = parseData(jQuery(form).serializeArray()); var f = document.createElement('form'); for (var key in data) { jQuery('').attr({ 'type': 'hidden', 'name': key, 'value': data[key] }).appendTo(f); } f.setAttribute('method', form.getAttribute('method')); f.setAttribute('action', form.getAttribute('action')); f.submit(); }
每当我想提交表单时,都会附加一个click
事件处理程序。 它将调用sendFormData(myOriginalForm);
而不是myOriginalForm.submit();
因为我需要自定义要发送的数据。
只有应用这些简单的更改,一切都会再次起作用。
不过,我正在寻找关于这种奇怪行为的解释。
在服务器端
HTTP请求是无状态的,会话通过不同的方式放在HTTP之上
- URL重写 (例如,服务器启动新会话并将其ID返回给客户端,然后客户端将会话ID附加到所有后续请求
http://host:port/path;session_id=12345
) - cookie (例如,在会话创建服务器上使用cookie编码会话ID进行响应,并且在服务器端,您希望cookie将每个请求与现有会话相关联)。
客户有责任确保他们通过服务器预期的方式参与会话。 当使用Java Servlet API实现服务器时,它是jsessionid cookie或具有相同名称的查询参数附加到URL,后者标识会话ID。
如果客户端不支持cookie,则使用Java Servlet API,您将不得不重定向到由HttpServletResponse.encodeRedirectURL(String url)
创建的HttpServletResponse.encodeRedirectURL(String url)
。
为了从servlet重定向,使用HttpServletResponse.sendRedirect(String url);
。
使用HTTP重定向标准对服务器进行响应将简化您的设计。 Jquery确实实现了这些标准,因此在这里将来自服务器的HTTP 301和302响应,因此不需要客户端上的重定向逻辑。
在客户端
您的客户端是jquery ,当后续请求将发送到同一域时,其ajax实现将尊重并重放为任何给定域设置的cookie。
如果要重定向到其他域, 要使jquery与CORS会话一起使用,请将xhrFields
到您的请求中:
$.ajax({ url: a_cross_domain_url, xhrFields: { withCredentials: true } });
根据这个答案
您是否尝试过不同forms的Javascript重定向?
推荐的方法是:
window.location.href=currentUrl;
根据这篇文章 ,使用window.location.replace
将替换当前会话。
- 使用jquery幻灯片,Ajax在JSF中无法正常工作
- jQuery和Java applet
- JQuery $(’#image’)。addimagezoom,用于从数据库中分散的图片
- 415尝试在Jax-RSjersey中发送FormData()时的状态
- 通过AJAX上传图片,不能在jQuery中使用serialize()方法?
- 如何使用javascript将jsp包含在另一个jsp中
- 如何在java中为键值对创建JSON数组,并在JQuery自动完成中使用它来分离KEY VALUE
- 在html表中填充上传的文件名和大小,在用户第二次选择文件时附加新值
- Java Spring REST API CORS不适用于通过jQuery与Chrome进行DELETE请求