حدث JSessionID في جميع عناوين URL التي يتم إنشاؤها بواسطة JSTL TAG

StackOverflow https://stackoverflow.com/questions/1045668

  •  20-08-2019
  •  | 
  •  

سؤال

لدي بعض الأخطاء الغريبة: عندما أفتح الصفحة لأول مرة في بعض المتصفح ، تحتوي جميع المراجع على معلمة JSessionID (مثل <a href="/articles?name=art&jsessionid=5as45df4as5df"..>).

عندما أضغط على F5 أو قم بتحديث الصفحة بأي طريقة أخرى يتم اختفاء كل هذه الأشياء وكل شيء يعمل بشكل جيد حتى أغلق متصفحي (ويجب إغلاق جميع علامات التبويب أيضًا). عندما أفتحه مرة أخرى أرى هذه المعلمة jsessionid الغريبة.

أنا استخدم JSTL <c:url..> علامة لإنشاء جميع عناوين URL.

لقد قرأت منذ بعض الوقت أن JSessionID هو بديل لملفات تعريف الارتباط إذا تم تعطيل ملفات تعريف الارتباط ، ولكن تم تمكين ملفات تعريف الارتباط وأنا في الواقع لا تستخدم ملفات تعريف الارتباط.

هل كانت مفيدة؟

المحلول

هذا ليس خطأ ، إنه حسب التصميم. عند إنشاء جلسة جديدة ، ليس الخادم متأكدًا مما إذا كان العميل يدعم ملفات تعريف الارتباط أم لا ، وبالتالي فهو يولد ملف تعريف ارتباط وكذلك JSessionID على عنوان URL. عندما يعود العميل للمرة الثانية ، ويعرض ملف تعريف الارتباط ، يعرف الخادم أن JSessionID ليس ضروريًا ، ويسقطه لبقية الجلسة. إذا عاد العميل بدون ملف تعريف ارتباط ، فيجب أن يستمر الخادم في استخدام إعادة كتابة JSessionID.

لا يجوز لك استخدام ملفات تعريف الارتباط بشكل صريح ، ولكن لديك ضمنيًا جلسة ، وتحتاج الحاوية إلى تتبع تلك الجلسة.

نصائح أخرى

كما أوضح في إجابة سكافمان, انها ليست خطأ. إنه سلوك متوقع.

في سؤالك ، يتم إلحاق JSessionID كمعلمة ، وهذا ليس هو الحال.
استخدام
<c:url value="/"/>
سوف يولد شيئًا مثل ما يلي: /some/;jsessionid=E85FAC04E331FFCA55549B10B7C7A4FA.
لذلك باستخدام
<link href="<c:url value="/"/>stylesheets/style.css" rel="stylesheet" type="text/css"/>
سوف يولد
/some/;jsessionid=E85FAC04E331FFCA55549B10B7C7A4FAstylesheets/style.css
، لذلك لا يمكن لخادمك العثور على المورد المتاح.

أفضل حلول وجدته هو استعمال ${pageContext.request.contextPath} بدلاً من <c:url value="/"/>. لذلك في المثال السابق ، سيكون لديك
<link href="${pageContext.request.contextPath}/stylesheets/style.css" rel="stylesheet" type="text/css"/>
التي سوف تولد
/some/stylesheets/style.css.

هذا الحل هو حاوية مستقلة (في حين أن الحاوية المتوافقة مع مواصفات Servlet V3 - مثل Tomcat - الحل ليس كذلك). إن تصفية عنوان URL للاستجابة يبدو وكأنه اختراق ، لأنه تحتاج إلى تغيير سلوك افتراضي. ولكن كل ما يتوقف على ما تحتاجه وتريد تحقيقه.

على Tomcat 7 أو أي خادم متوافق مع مواصفات Servlet V3 ، يمكنك تعطيل JSessionID في عنوان URL عن طريق إضافة متابعين إلى web.xml من التطبيق الخاص بك

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

إليك حل بديل سيء في نكهة أ Filter حتى لا ترى jsessionid في عنوان URL كلما دعم العميل ملفات تعريف الارتباط.

@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 الذي يتطلب إدارة الجلسة.

إذا كان لديك صفحة غلاف شائعة تستخدمها جميع الصفحات (بالنسبة لي كانت شائعة. 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]

لسوء الحظ ، فإن الطريقة الوحيدة التي وجدتها حول هذا هي إضافة مرشح إلى تطبيقك الذي سيؤدي إلى تجريد المعلمة JSessionID. إنه أمر مزعج بشكل خاص إذا كنت تقوم بإنشاء موقع ويب عام وتريد أن تفهرس محركات البحث في صفحاتك.

لا أعتقد أنه يمكن تكوين Tomcat (إذا كان هذا ما تستخدمه) لعدم إضافة هذا إلى عنوان URL الخاص بك. لا أستطيع أن أقول للخوادم الأخرى رغم ذلك.

ومع ذلك ، لاحظ أنه إذا قمت بإنشاء الفلتر وترغب بعد ذلك في إدارة الجلسة وإيقاف تشغيل المستخدم ، فستواجه مشكلات.

حل واحد هو عدم الاستخدام <c:url>, ، ولكن للاستخدام ${request.contextPath}/path

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top