jsessionid 出现在 jstl 生成的所有 url 中 标签

发布于 2024-07-25 10:11:07 字数 406 浏览 6 评论 0 原文

我遇到了一些奇怪的错误:当我第一次在某些浏览器中打开页面时,所有引用都有 jsessionid 参数(例如 )。

当我按 F5 或通过任何其他方式刷新页面时,所有这些内容都会消失,并且一切正常,直到我关闭浏览器(并且所有选项卡也应该关闭)。 当我再次打开它时,我看到这个奇怪的 jsessionid 参数。

我使用 jstl 标签来创建所有 URL。

我前一段时间读过,如果禁用cookie,jsessionid是cookie的替代品,但是启用cookie并且我实际上不使用cookie。

I've got some strange bug: when I open page first time in some browser all references has jsessionid parameter (like <a href="/articles?name=art&jsessionid=5as45df4as5df"..>).

When I press F5 or refresh the page by any other ways all that stuff is disappeared and everything works fine until I close my browser (and all tabs should be closed too). When I open it again I see this strange jsessionid parameter.

I use jstl <c:url..> tag for creating all URLs.

I've read some time ago that jsessionid is an alternative to cookies if cookies are disabled, but cookies are enabled and I actually don't use cookies.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

对风讲故事 2024-08-01 10:11:07

这不是错误,而是设计使然。 当创建新会话时,服务器不确定客户端是否支持 cookie,因此它会生成 cookie 以及 URL 上的 jsessionid。 当客户端第二次返回并呈现 cookie 时,服务器知道 jsessionid 不是必需的,并在会话的其余部分中将其删除。 如果客户端返回没有cookie,那么服务器需要继续使用jsessionid重写。

您可能没有显式使用 cookie,但您确实隐式拥有一个会话,并且容器需要跟踪该会话。

This isn't a bug, it's by design. When a new session is created, the server isn't sure if the client supports cookies or not, and so it generates a cookie as well as the jsessionid on the URL. When the client comes back the second time, and presents the cookie, the server knows the jsessionid isn't necessary, and drops it for the rest of the session. If the client comes back with no cookie, then the server needs to continue to use jsessionid rewriting.

You may not explicitly use cookies, but you do implicitly have a session, and the container needs to track that session.

烟─花易冷 2024-08-01 10:11:07

正如 skaffman 的回答中所解释的,这不是一个错误。 这是预期的行为

在您的问题中, jsessionid 被附加为参数,但情况并非如此。
使用

将生成如下内容:/some/;jsessionid=E85FAC04E331FFCA55549B10B7C7A4FA
所以使用
stylesheets/style.css" rel="stylesheet" type="text/css"/>
将生成
/some/;jsessionid=E85FAC04E331FFCA55549B10B7C7A4FAstylesheets/style.css
,因此您的服务器无法找到可用的资源。

我发现的最佳解决方法是使用${pageContext.request.contextPath}而不是< /强>。 所以在前面的例子中,你会

这将生成
/some/stylesheets/style.css

该解决方案是容器独立的(而符合 servlet 规范 v3 的容器 - 如 Tomcat - 解决方案则不是)。 过滤响应 URL 感觉就像黑客,因为您需要更改默认行为。 但这一切都取决于您的需要和想要实现的目标。

As explained in skaffman's answer, its not a bug. Its an expected behavior.

In your question the jsessionid is appended as a parameter, which is not the case.
Using
<c:url value="/"/>
will generate something like the following: /some/;jsessionid=E85FAC04E331FFCA55549B10B7C7A4FA.
So using
<link href="<c:url value="/"/>stylesheets/style.css" rel="stylesheet" type="text/css"/>
will generate
/some/;jsessionid=E85FAC04E331FFCA55549B10B7C7A4FAstylesheets/style.css
, so your server cannot find the resource available.

The best workaround that I found is to use ${pageContext.request.contextPath} instead of <c:url value="/"/>. So in the previous example, you would have
<link href="${pageContext.request.contextPath}/stylesheets/style.css" rel="stylesheet" type="text/css"/>
that will generate
/some/stylesheets/style.css.

This solution is container independent (whereas the servlet specification v3 compliant container - like Tomcat - solution is not). Filtering the response url feels like a hack, cause you need to change a default behavior. But all depends on what you need and want to achieve.

思慕 2024-08-01 10:11:07

在 Tomcat 7 或任何符合 servlet 规范 v3 的服务器上,您可以通过将以下内容添加到应用程序的 web.xml 来禁用 URL 中的 jsessionid

<session-config>
    <tracking-mode>COOKIE</tracking-mode>
</session-config>

On Tomcat 7 or any servlet specification v3 compliant server you can disable jsessionid in URL by adding following to the web.xml of your application

<session-config>
    <tracking-mode>COOKIE</tracking-mode>
</session-config>
娇妻 2024-08-01 10:11:07

这是一个类似于 Filter 的令人讨厌的解决方法,这样只要客户端支持 cookie,您就永远不会在 URL 中看到 jsessionid。

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    HttpServletRequest req = (HttpServletRequest) request;
    HttpServletResponse res = (HttpServletResponse) response;
    HttpSession session = req.getSession();

    if (session.isNew()) {
        // New session? OK, redirect to encoded URL with jsessionid in it (and implicitly also set cookie).
        res.sendRedirect(res.encodeRedirectURL(req.getRequestURI()));
        return;
    } else if (session.getAttribute("verified") == null) {
        // Session has not been verified yet? OK, mark it verified so that we don't need to repeat this.
        session.setAttribute("verified", true);
        if (req.isRequestedSessionIdFromCookie()) {
            // Supports cookies? OK, redirect to unencoded URL to get rid of jsessionid in URL.
            res.sendRedirect(req.getRequestURI().split(";")[0]);
            return;
        }
    }

    chain.doFilter(request, response);
}

将其映射到 /* 或任何需要会话管理的 URL 模式。

Here's a nasty workaround in flavor of a Filter so that you will never see the jsessionid in URL whenever the client supports cookies.

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    HttpServletRequest req = (HttpServletRequest) request;
    HttpServletResponse res = (HttpServletResponse) response;
    HttpSession session = req.getSession();

    if (session.isNew()) {
        // New session? OK, redirect to encoded URL with jsessionid in it (and implicitly also set cookie).
        res.sendRedirect(res.encodeRedirectURL(req.getRequestURI()));
        return;
    } else if (session.getAttribute("verified") == null) {
        // Session has not been verified yet? OK, mark it verified so that we don't need to repeat this.
        session.setAttribute("verified", true);
        if (req.isRequestedSessionIdFromCookie()) {
            // Supports cookies? OK, redirect to unencoded URL to get rid of jsessionid in URL.
            res.sendRedirect(req.getRequestURI().split(";")[0]);
            return;
        }
    }

    chain.doFilter(request, response);
}

Map it on /* or whatever URL pattern which require session management.

埋葬我深情 2024-08-01 10:11:07

如果您有一个所有页面都使用的通用包装页面(对我来说是 common.inc)
您可以将 session="false" 添加到您的 <%@ page 以删除 sessionid。

示例 common.inc

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" session="false" trimDirectiveWhitespaces="true" %>
<%@ taglib prefix="ab" tagdir="/WEB-INF/tags" %>

<c:set var="contextPath" scope="request" value="${ pageContext.request.contextPath }" />
<c:set var="assetPath" scope="request" value="/assets" />
<c:set var="debugEnabled" scope="request" value="${ applicationDebugProperties.debugEnabled }" />

或者.. 将 c:url 的值设置为变量并使用 c:out escapeXml="false" 输出变量,这将删除 sessionid。

示例:

<c:url value=${url} var="image"/>
<c:out var=${image} escapeXml="false"/>

或者,您可以将其添加到 Apache 配置中以截断 sessionid。

ReWriteRule ^/(\w+);jsessionid=\w+$ /$1 [L,R=301]
ReWriteRule ^/(\w+\.go);jsessionid=\w+$ /$1 [L,R=301]

If you have a common wrapper page that all pages use (for me it was common.inc)
you can add session="false" to your <%@ page to remove the sessionid.

Example common.inc

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" session="false" trimDirectiveWhitespaces="true" %>
<%@ taglib prefix="ab" tagdir="/WEB-INF/tags" %>

<c:set var="contextPath" scope="request" value="${ pageContext.request.contextPath }" />
<c:set var="assetPath" scope="request" value="/assets" />
<c:set var="debugEnabled" scope="request" value="${ applicationDebugProperties.debugEnabled }" />

Alternatively.. set the value of c:url to a variable and use c:out escapeXml="false" to output the variable and this will remove the sessionid.

Example:

<c:url value=${url} var="image"/>
<c:out var=${image} escapeXml="false"/>

Alternatively, you can add this to your Apache configuration to truncate the sessionid.

ReWriteRule ^/(\w+);jsessionid=\w+$ /$1 [L,R=301]
ReWriteRule ^/(\w+\.go);jsessionid=\w+$ /$1 [L,R=301]
时光沙漏 2024-08-01 10:11:07

一种解决方法是不使用 ,而是使用 ${request.contextPath}/path

One workaround is not to use <c:url>, but to use ${request.contextPath}/path

私藏温柔 2024-08-01 10:11:07

不幸的是,我发现解决此问题的唯一方法是向您的应用程序添加一个过滤器,该过滤器将删除 jsessionid 参数。 如果您正在创建一个公共网站并希望搜索引擎为您的页面建立索引,那么这尤其令人烦恼。

我不相信tomcat(如果您正在使用它)可以配置为不将其添加到您的网址中。 但我不能说其他服务器。

但是,请注意,如果您创建了过滤器,然后需要会话管理,并且用户关闭了 cookie,您将会遇到问题。

Unfortunately the only way I have found around this is to add a filter to your application that will strip out the jsessionid parameter. Its particularly annoying if you are creatinga public website and want th esearch engines to index your pages.

I do not believe that tomcat (if that's what you're using) can be configured to not add this to your url. I can't say for the other servers though.

However, note that if you do create the filter and you then require session management and the user has cookies turned off you will run into problems.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文