[英]Session attribute is lost after invoking a client-side redirect
以前,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 頁面中插入<%= session.getId() %>
比較了會話 ID。 他們是一樣的。 這里的問題是session.getAttribute("myAttribute_1")
在重定向到的頁面中返回null
。
我不確定這是否重要,但實際上我正在使用 1 個以上的 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);
}
});
}
我已經恢復使用response.sendRedirect("pages/my_page.jsp?foo=bar")
在我的 servlet 中。
在客戶端, jQuery.ajax()
被刪除, sendFormData()
函數更新如下。
function sendFormData(form) {
var data = parseData(jQuery(form).serializeArray());
var f = document.createElement('form');
for (var key in data) {
jQuery('<input>').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();
因為我需要自定義要發送的數據。
只有通過應用這些簡單的更改,一切才能恢復正常。
不過,我正在尋找對這種奇怪行為的解釋。
您是否嘗試過其他形式的Javascript重定向?
推薦的方法是:
window.location.href=currentUrl;
根據本文的介紹 ,使用window.location.replace
將替換當前會話。
HTTP請求是無狀態的,會話通過不同的方式位於HTTP之上
http://host:port/path;session_id=12345
) 客戶有責任通過服務器期望的方式確保他們參與會話。 使用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
}
});
按照這個答案
我遇到了同樣的問題,並撕毀了我的頭發以尋找最佳解決方案。 嘗試將sessionCookiePath="/"
屬性放入您的 context.xml 根節點:
<Context ... sessionCookiePath="/" > ... </Context>
這會將會話 cookie 的路徑設置為應用程序的根目錄,以便在重定向時傳遞。 這個簡單的修復對我有用。
許多人會建議 URL 編碼或將會話 ID 存儲在另一個 cookie 中,但根據我的理解,如果它適合您,這是最好的解決方案。 (會話 cookie 被認為是絕對必要的,因此按預期使用它們可能是最佳實踐。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.