Link to home
Start Free TrialLog in
Avatar of JohnWeidner
JohnWeidner

asked on

Detecting access to .jsp outside of frame

My web site uses frames with individual frames for a tool bar and another one for the main content.   Is there a way on the server side to detect when someone is trying to access the main content frame without the parent frameset being displayed?   If someone clicks on a link (from a search engine) to the main content page, I want to make sure that the toolbar frame is also displayed.
Avatar of knightEknight
knightEknight
Flag of United States of America image

I would handle this on the client.  In your main content page, do this:

<SCRIPT language='javascript'>
 if (parent.frames.length==0)
   top.location="frameset.jsp?mainpage=" + location.href;
</script>

ASKER CERTIFIED SOLUTION
Avatar of knightEknight
knightEknight
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of JohnWeidner
JohnWeidner

ASKER

That's what I was thinking I'd have to do.   I was just wanting to catch it on the server side before the first page got to the browser if that were possible.
I just noticed the "referer" entry in the header.   Would there be any problem with something like this?

<%
    if ( request.getHeader( "referer" ) == null )
    {
        // request has come from outside of the frame
        targetPage = HttpUtils.getRequestURL( request );
        session.setAttribute( "mainPage", targetPage );
%>
      <jsp:forward page="frameset.jsp" />
<%
    }
%>

and then in frameset.jsp have


<%
 String mainpage = session.getAttribute("mainPage");
 if ( mainpage==null ) {
    mainpage = "default.jsp";
  }
%>

...

 <FRAME name="main" src="<%=mainpage%>" > 
From your use of a deprecated ( HttpUtils.getRequestURL )  
I assume you are using pre-Servlet2.3  
But if you could use Servlet2.3  have you considered  
using  Filters.  
rrz: filters execute on the server side.  You can get the requested URI/URL but not the actual URL in the browser location box.  So Java won't know that it is in a frame.

JavaScript must be use to check for being framed and to enforce the navigation frame.

CJ

to cheekyci,
JohnWeidner wrote  
>If someone clicks on a link (from a search engine) to
the main content page, I want to make sure that the toolbar frame is also displayed.
   
So what I am suggesting is to  use a Filter to redirect any request for the main content page to the frameset page.
rrz: the problem is that the filter cannot know the exact origin of the request.  It knows what page is requested.

For example, if I have frame.htm (with two frames split horizontally) which has my own html nav on top and a servlet for the bottom part.  The filter can detect that bottomFrame Servlet has been called.. but the filter actually has NO clue that frame.htm is calling it as a part of the frame.

You can filter requests to bottomFrame Servlet but how do you differentiate when frame.htm is on your site versus another site?  the Servlet's URI will always be the same.

Hence, a JavaScript solution is needed.

CJ
A filter cannot detect whether the page was called directly or from a frame.
I will describe my idea in more detail. I really don't know if it can be done. I have not tried to write the code yet.    
The web site pages that JohnWeidner wants to access contain
a frameset. Make those pages JSP, for example FrameSetX.jsp.   FramSetX.jsp could  have the code request.setAttribute("token","token"); . The main content page, MainContent.jsp is designated as the URL to which the Filter applies. The Filter has the logic to decide if the token is present in the request. If token is null then the Filter redirects to FrameSetX.jsp .  
Is this feasable ?
I am not sure here.

The filter is not applied to FrameSetX.jsp since you want that accessible.. and it will attach a token and forward to the MainContent.jsp.. I don't know if filter's are applied to servlet/jsp forwards.. I thought they went by requested URL.

CJ
I wrote the code. My idea does work but seems like a lot of work if JavaScript can do the job. It doesn't work by setting a request object. I got it to work two ways, the first way by using a session object, the second way by using a query string.  Either way the web.xml file should be edited to include the following.  
            <filter>
                    <filter-name>Entry</filter-name>
                    <filter-class>myPackage.EntryFilter</filter-class>
           </filter>
           <filter-mapping>
                     <filter-name>Entry</filter-name>
                     <url-pattern>/jspPackage/MainContent.jsp</url-pattern>
           </filter-mapping>  

--------EntryFilter.java---------------------------------
 package myPackage;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class EntryFilter implements Filter{
public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain)
                   throws ServletException, IOException {
         HttpServletResponse resp = (HttpServletResponse)response;
         HttpServletRequest req =  (HttpServletRequest)request;
         if(req.getSession().getAttribute("token")==null)resp.sendRedirect("/MyContext/jspPackage/FrameSetX.jsp ");  
//second way// if(request.getParameter("token")==null)resp.sendRedirect("/MyContext/jspPackage/FrameSetX.jsp");
         chain.doFilter(request,response);
}
public void init(FilterConfig config) throws ServletException{}
public void destroy(){}
}
------------------------------------------------------
In  FrameSetX.jsp  include the following(second way commented out);

<frameset rows="xx,*">
<%
  session.setAttribute("token","token");
%>
<frame name="top" src="Toolbar.jsp"/>
<frame name="bottom" src="MainContent.jsp"/>
<%-- <frame name="bottom" src="MainContent.jsp?token=token"/> --%>
</frameset>