Application / Environement Setup:
JSF 2.2 (Mojarra)
Primefaces v 7.0.0 (03.2019)
Component p:outputPanel with deffered loading
What we expect is that the xhr request will be send to the same URL (service) where the component is embedded (used).
Let's assume the url where the component is used is: https://www.example.com/ad/product_123
The xhr call is not send to the above url, instead its going to https://www.example.com/search.jsf.
Inside the xhtml page we use a plain html form in the header for user search inputs. I guess, that the javascript function, which collecting the url for the xhr call is grabbing the wrong url?
how can i verify where the primefaces p:outputPanel component with deffered=true is grabing the url, which will be used called?
example xhr
{"Formulardaten":{"javax.faces.partial.ajax":"true","javax.faces.source":"j_idt182","primefaces.ignoreautoupdate":"true","javax.faces.partial.execute":"j_idt182","javax.faces.partial.render":"j_idt182","j_idt182":"j_idt182","j_idt182_load":"true","search":""}}
as you can the inside the xhr request, it is involving a parameter 'search' which we declared in our plain html form.
Thanks
Related
As per my code , I have to render jsf component clicking on radio button .so I have ajax event of Type 'click' , and want to add in the listener attribute that it has to render this jsf component. I have the client ID of that jsf component with me. planning to write the method in controller class.So how can I achieve this in java bean side?
any help is appreciable.
I was following this answer by BalusC to try and upload a file to the server. I am using his code as-is.
When using JSF 2.2, the #{bean.save} was never reached, and the file was never saved.
The server's console showed nothing. But the js console showed this error:
Refused to display 'http://localhost:8080/my_app/hello.xhtml' in a frame because it set 'X-Frame-Options' to 'deny'.
jsf.js.xhtml?ln=javax.faces:1 Uncaught DOMException: Blocked a frame with origin "http://localhost:8080" from accessing a cross-origin frame.
at FrameTransport.callback (http://localhost:8080/my_app/javax.faces.resource/jsf.js.xhtml?ln=javax.faces:1:5109)
at HTMLIFrameElement.<anonymous> (http://localhost:8080/my_app/javax.faces.resource/jsf.js.xhtml?ln=javax.faces:1:5759)
I saw this answer which suggested it was a bug in JSF 2.2. So I uploaded to 2.3.
With JSF 2.3 the #{bean.save} is reached, and the file is successfully saved. But the js error remains, and I can't upload a second file.
Any ideas?
EDIT in case it helps: I don't know why, but after selecting the file to upload in the dialog, an <iframe> is added to my page somehow.
EDIT 2
BalusC and Selaron suggested I try to change the X-Frame-Options header to not 'DENY'. I tried adding a #WebFilter and setting the header there, like this:
public void doFilter(...)
{
HttpServletResponse response = (HttpServletResponse) res;
response.addHeader("X-Frame-Options", "sameorigin");
response.setHeader("MyHeader", "whatever");
chain.doFilter(req, res);
}
I added a second header MyHeader with value "whatever" to check if the response contained that header when getting to the browser.
Turns out MyHeader gets to the browser correctly, but X-Frame-Options still remains as 'DENY'.
As I'm using Spring Security, I figured maybe there was some other filter messing with my response?
So, I have this:
#Configuration
#EnableWebSecurity
public class BasicConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
...
http.addFilterAfter(
new CustomFilter(), SwitchUserFilter.class);
...
}
}
My CustomFilter works as the previous one I showed: MyHeader remains, but X-Frame-Options does not.
I added it after SwitchUserFilter because the doc for HttpSecurity.addFilter says that is the last filter in the chain.
I am a bit lost now. My couple of questions:
Am I right to assume the X-Frame-Options header is getting overwritten by some other filter?
How could I ensure the X-Frame-Options I set remains? Or, how can I put my filter at the end of the chain?
I found this issue where the Mojarra team planned to Implement "ajax" file upload #2577 and the commit actually implementing it to the jsf javascript.
Madly the documentation on issue 2577 are not accessible anymore and thus it does not explain the background on why an iframe is needed here.
The first passage of this blog gives a brief explanation on why AJAX file upload is/was(?) not possible directly:
Ajax Style File Uploading using Hidden iFrame
by Viral Patel · November 18, 2008
File uploading using AJAX is not possible. AJAX doesn’t actually post
forms to the server, it sends selected data to the server in the form
of a POST or GET request. As javascript is not capable of grabbing the
file from the users machine and sending it to the server, it’s just
not possible with AJAX. You have to resort to regular old form submit.
If you have read/seen it somewhere, then it is not through AJAX. File
uploading occurs through an iframe in this case. You have to use a
iframe to upload the files. So, you can use iframe to asynchronous
upload (Like AJAX , but its not AJAX).
So finally your options are to either - as BalusC commented - relax your X-Frame-Options header setting or to change your upload to not use AJAX:
<h:form enctype="multipart/form-data">
<h:inputFile value="#{bean.file}" />
<h:commandButton value="upload" action="#{bean.save}"/>
</h:form>
My app is using Tomee 7.0.5, Java 8, MySql, JSF 2.2, Omnifaces 2.7. Primefaces 6.1, Prettyfaces 3.3.3. I tried to use Omnifaces' ViewScoped annotation together with #Named in my backing bean. It is required to use OWASP to validate requests. For some unknown reason a click on a link is converted to a POST request and since this link is used to navigate to another page there is no token yet in the request and so the validate request fails. Now, if I use javax.faces.view.ViewScoped instead everything is fine. I have 12 applications with the same pattern.
Each app has a template with a p:toolbar and links to navigate like:
<h:link outcome="pretty:search" value="Search"
onclick="showSpinningIcon();return true;" />
No errors in Chrome console. what am I missing here?
I am having issues with the Omnifaces FullAjaxExceptionHandler (http://showcase.omnifaces.org/exceptionhandlers/FullAjaxExceptionHandler). It does not redirect to the specified error page after the session is invalidated.
I have the following in my faces-config:
<factory>
<exception-handler-factory>org.omnifaces.exceptionhandler.FullAjaxExceptionHandlerFactory</exception-handler-factory>
</factory>
And the following in my web.xml:
<error-page>
<exception-type>javax.faces.application.ViewExpiredException</exception-type>
<location>/pages/error/viewExpired.html</location>
</error-page>
After I invalidate the session, from a user's perspective nothing seems to happen. The application is just 'dead'. In my console I see the following Ajax request:
A POST to the original facelet page with a response code of 302
a GET to the login page with a code 200 (but nothing happens because it's requested via Ajax)
I am running MyFaces 2.1.10, Primefaces 3.5, Primefaces Extension 0.6.3 & Omnifaces 1.4.1 on WebLogic 12c
Could anyone help me in the right direction? How do I get the FullAjaxExeptionHandler to work properly?
Thanks
A POST to the original facelet page with a response code of 302
This is not right. A redirect on a JSF ajax request must have a response code of 200 with a special XML response with a <redirect> element with target URL in its url attribute.
This thus indicates that you manually used HttpServletResponse#sendRedirect() somewhere long before JSF has the chance to deal with ViewExpiredException.
Perhaps you've somewhere a servlet filter which checks some session attribute and sends a redirect based on its presence/state? That filter should then be manipulated based on the following answer: JSF Filter not redirecting After Initial Redirect in order to recognize JSF ajax requests and return a special XML response instead of a 302 response.
E.g.
if ("partial/ajax".equals(request.getHeader("Faces-Request"))) {
response.setContentType("text/xml");
response.getWriter()
.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>")
.printf("<partial-response><redirect url=\"%s\"></redirect></partial-response>", loginURL);
} else {
response.sendRedirect(loginURL);
}
This all is completely unrelated to the FullAjaxExceptionHandler. JSF didn't have any chance to throw a ViewExpiredException because you're already sending a redirect yourself beforehand.
I have a requirement that a jsf page needs to be launched from a custom thin client in user browser (thin client does a http post). Since the jsf page may be invoked multiple times, I use a jsp to redirect to the jsf page with params on url. In jsp I do a session invalidation. The jsp code is below:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<%#page session="true" %>
<%
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Pragma", "no-cache");
session.invalidate();
String outcome = request.getParameter("outcome");
String queryString = "outcome=" + outcome ;
response.sendRedirect("./faces/MyPage.jspx?" + queryString);
%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252"></meta>
<title>title here</title>
</head>
<body></body>
</html>
My jsf page uses mutiple drop down items with autoSubmit enabled. I set the params on session when the form first inits and then use it from there when an action button is ultimately clicked by user. Following is the code I use to get the param in jsf backing bean constructor:
FacesContext ctx = getFacesContext();
Map sessionState = ctx.getExternalContext().getSessionMap();
outcome = (String)sessionState.get("outcome");
if(outcome == null) //if not on session, get from url
outcome = (String)JSFUtils.getManagedBeanValue("param.outcome");
This way I can get the param even after multiple autoSubmits of drop downs.
My problem is that I cannot have parameters show up on browser address bar. I need a way so that the parameters can be passed to the jsp page. I cannot post direct to jsp from thin client since I need the jsf page to have a new session each time the client launches user browser. This is imp due to the above code snippet on how I use params in the jsf page.
Is there nay way to use a post when doing a sendRedirect so that I do not have to pass params on url? I cannot use forward since when an autoSubmit fires on jsf page, it causes the browser to refresh the jsp page instead.
Is there any better way to handle the jsf page itself so that I don't have to rely on storing params on session between successive autoSubmit events?
Since you invalidate the session, no, you cannot.
The only way would be putting it in the session scope. Why are you by the way invalidating the session on first request? This makes really no sense.
Unrelated to your actual problem, doing sendRedirect() in a scriptlet instead of a Filter and having a bunch of HTML in the same JSP page is receipt for big trouble. Do not write raw Java code in JSP files, you don't want to have that. Java code belongs in Java classes. Use taglibs/EL in JSP only.
No. Because sendRedirect send the web-browser/client a 302 with the new location and according to the following it will usually be a GET, no matter what the original request was.
According to HTTP/1.1 RFC 2616 http://www.ietf.org/rfc/rfc2616.txt:
If the 302 status code is received in response to a request other
than GET or HEAD, **the user agent MUST NOT automatically redirect the
request unless it can be confirmed by the user**, since this might
change the conditions under which the request was issued.
Note: RFC 1945 and RFC 2068 specify that the client is not allowed
to change the method on the redirected request. However, ***most
existing user agent implementations treat 302 as if it were a 303
response, performing a GET on the Location field-value regardless
of the original request method***. The status codes 303 and 307 have
been added for servers that wish to make unambiguously clear which
kind of reaction is expected of the client.
Maybe playing carefully with ajax can get you something.
Update: Then again, as user: BalusC pointed out, you can redirect by manually setting the headers, as in:
response.setStatus(307);
response.setHeader("Location", "http://google.com");