My All Js and css are in script.jsp file and include on every page
<jsp:include page="../include/scripts.jsp" />
when page submit / refresh it reload again and again ?
How to control this ?
Here's an explanation I found that could explain it. It helped me out when i needed it
Here's an explanation of the problem...
Clicking the "submit" button on a form sends a request to the web server, which includes all the data entered on the form. Not only the URL but also the form data is part of the request, and this request is remembered by the browser. If the user clicks "refresh", the browser repeats the request, sending the same URL and form data to the web server again.
But forms can be submitted in two different ways, GET or POST, depending on the "method" attribute of the "form" tag. There is a convention that a GET request has no side-effects; it only fetches data but does not make any changes to the database. On the other hand, if a request changes data it should always use a POST request. As I said, these are only conventions, and there is not much technical difference between them, but a very important difference is that browsers will warn the user if they try to repeat a POST -- clicking "refresh" will pop up a dialog box warning the user that this may cause an operation to be repeated, and confirming that they really want to resubmit. The browser does not show this confirmation when refreshing a GET request.
Is your form using the GET method changing it to POST is the simplest solution, since this will at least mean that the user is warned if they try to refresh.
But a better solution is the POST+REDIRECT+GET idiom suggested by #cletus. This splits the database update (POST) and the view (GET) into two operations. Clicking refresh on the browser then merely repeats the GET, which has no side-effects.
Use the include directive <%# include/> as against the <jsp:include/> tag you're using now.
<jsp:include/> will instruct the jsp runtime to go and fetch the included resource everytime the compiler comes across that tag (first-time requests, refreshes) while <# include/> means that the included resource is built into the parent resource at compile-time
The difference is that the directive is a compile-time include. This means that the content of the directive (in your case scripts.jsp) is baked into the parent jsp (and ultimately the servlet that the jsp will be compiled into). The effect is that the included file is read only the first time the parent jsp is rendered.
What you should have:
<%# include page="../include/scripts.jsp" />
Related:
What is the difference between <jsp:include page = ... > and <%# include file = ... >?
Related
I am currently learning JSF and was rather amazed and puzzled when I realized that whenever we use <h:form>, the standard behavior of JSF is to always show me the URL of the previous page in the browser, as opposed to the URL of the current page.
I understand that this has to do with the way JSF always posts a form to the same page and then just renders whatever page the controller gives it back to the browser which doesn't know the page location has changed.
It seems like JSF has been around for long enough that there must be a clean, solid way to deal with this. If so, would you mind sharing?
I have found various workarounds, but sadly nothing that seems like a real solid solution.
Simply accept that the URL is misleading.
Append "?faces-redirect=true" to the return value of every bean's action and then
figure out how to replace #RequestScoped with something else (Flash Scopes, CDI conversation, #SessionScoped, ...).
accept to have two HTTP round trips for every user action.
Use some method (e.g. 3rd party library or custom code) to hide the page name in the URL, always using the same generic URL for every page.
If "?faces-redirect=true" is as good as it gets, is there a way do configure an entire application to treat all requests this way?
Indeed, JSF as being a form based application targeted MVC framework submits the POST form to the very same URL as where the page with the <h:form> is been requested form. You can confirm it by looking at the <form action> URL of the generated HTML output. This is in web development terms characterized as postback. A navigation on a postback does by default not cause a new request to the new URL, but instead loads the target page as content of the response. This is indeed confusing when you merely want page-to-page navigation.
Generally, the right approach as to navigation/redirection depends on the business requirements and the idempotence (read: "bookmarkability") of the request (note: for concrete code examples, see the "See also" links below).
If the request is idempotent, just use a GET form/link instead of POST form (i.e. use <a>, <form>, <h:link> or <h:button> instead of <h:form> and <h:commandXxx>).
For example, page-to-page navigation, Google-like search form, etc.
If the request is non-idempotent, just show results conditionally in the same view (i.e. return null or void from action method and make use of e.g. <h:message(s)> and/or rendered).
For example, in-page data entry/edit, multi-step wizard, modal dialog, confirmation form, etc.
If the request is non-idempotent, but the target page is idempotent, just send a redirect after POST (i.e. return outcome with ?faces-redirect=true from action method, or manually invoke ExternalContext#redirect(), or put <redirect/> in legacy XML navigation case).
For example, showing list of all data after successful editing, redirect after login, etc.
Note that pure page-to-page navigation is usually idempotent and this is where many JSF starters fail by abusing command links/buttons for that and then complain afterwards that URLs don't change. Also note that navigation cases are very rarely used in real world applications which are developed with respect to SEO/UX and this is where many JSF tutorials fail by letting the readers believe otherwise.
Also note that using POST is absolutely not "more secure" than GET because the request parameters aren't immediately visible in URL. They are still visible in HTTP request body and still manipulatable. So there's absolutely no reason to prefer POST for idempotent requests for the sake of "security". The real security is in using HTTPS instead of HTTP and checking in business service methods if currently logged-in user is allowed to query entity X, or to manipulate entity X, etc. A decent security framework offers annotations for this.
See also:
What is the difference between redirect and navigation/forward and when to use what?
JSF implicit vs. explicit navigation
What URL to use to link / navigate to other JSF pages
Bookmarkability via View Parameters feature
What can <f:metadata>, <f:viewParam> and <f:viewAction> be used for?
When should I use h:outputLink instead of h:commandLink?
Creating master-detail pages for entities, how to link them and which bean scope to choose
Retaining GET request query string parameters on JSF form submit
Pass an object between #ViewScoped beans without using GET params
Some users who navigate to my page do so via an url like this : http://domain/ProductDetail.aspx?Productid=123#Pricing
In this section is a asp:button to make a purchase. This button cause a postback, and when the page rerendering in the broswer the FragmentIdentifier #Pricing is still in the address window.
This is causing problems because there is new content rendered on the page which isn't visible if the browser navigates to the #Pricing section.
How do I prevent the FragmentIdentifier on postback?
Clarification:
It appears that this problem happens in Chrome but does not happen in IE8 or FireFox. Chrome holds on to the #FragmentIdentifier after postback even those there is no reference to it in the action attribute.
You can't, browser doesn't send it:
When a URI reference is used to perform a retrieval action on the
identified resource, the optional fragment identifier, separated from
the URI by a crosshatch ("#") character, consists of additional
reference information to be interpreted by the user agent after the
retrieval action has been successfully completed. As such, it is not
part of a URI, but is often used in conjunction with a URI.
How to get Url Hash (#) from server side
Browsers don't send URL fragments on the server side. You can't modify them the only option you can try is URL rewrite, if that helps. good luck...
The ASP.NET engine will cause a simple submit without any given URL, so the browser is forced to take the URL of the current page.
You can get rid of the hash after the postback by hooking a self executing javascript into the HTML that will replace the hash to an empty string.
Here is an example:
if(this.Page.IsPostback)
{
this.Page.ClientScript.RegisterStartupScript(this.GetType(), "RemoveHash", "window.location.hash=''", true);
}
You can force the browser to get rid of the # tag by redirecting to the same page.
When a client is on page A.aspx , and he press some button there is a postback.
The server knows which page to rebuild according to the request.
but how does the client knows which page to re-ask ? by the current url of his browser ?
where this information is saved in the client side ?
Its defined in the action property of <form>. The client does not need to re-ask, the server sends a response of his request.
ASP.NET is just a part of the .NET framework, but what every client sees on a web browser in plain old HTML.
ASP.NET gives you several controls that makes it easy to use them programatically, so we can set all sort of things in our code (that is run before the page is showing) to do the exactly what we want.
every link, button, image, grid, it's just HTML tags, like <a> for links, <input type="button"> for buttons etc...
Keep in mind that now, there are 2 variantes of the ASP.NET, the WebForms and the MVC (you can also read about choosing one in prole of the other)
in every ASP.NET WebForms there is always a <form> on the start of the <body> and wrapps all your code, so, any submit will do a PostBack into the same file name, in your example A.apsx will always post into A.aspx, then if you want, for example, send that request to B.aspx you need to have a Click Event that would use the Server.Transfer("B.aspx") and that would redirect the entire post to B.aspx just like it was a post from B.aspx
in the newest pattern, the ASP.NET MVC, it drives with Routes witch let's you set up any, every, one, multiple, ways to reach the same page. In MVC the URL does not point to a specific page, but to a specific Controller and it's up to the Controller to send, after processing the data, to a specific View, that is why in MVC there are no pages in the url (though you can add it to the route if you want, and you can accomplish the same with WebForms using a Routing plugin).
Now, in MVC it's there is no <form> wrapping up your entire code, you need to, if you want to submit something, create your own <form> and point to the correct route
but, just like in Webforms or any HTML page, posts are made through form submittion, and it's "path" it's always whats in the form attribute action that let's you know what's the next step.
I hope this helps you realizing that there is no big monster in ASP.NET, that is only a way to reuse controls and access them programmatically and that, in the end, it's all HTML :)
A general answer: on the client side it's either a submit from within a form or a link.
The form points to either a relative URL (that means the current URL plays a key role) or an absolute URL (the current URL plays little to no role).
For links it's generally the same: either they are relative or absolute. One big difference: links are use HTTP GET while forms can use HTTP POST (thus transferring more data without encoding them to the URL as parameters).
For a button it's the form that gets submitted.
I have an ASP.NET website where i have implemented page level caching using the OutPutCache directive.This boosted the page performance.My pages has few parts(Some buttons,links and labels) which are specific to the logged in user.If user is not logged in,they will see different links.Now Since i implemented the page level caching,Even after the user logged in,It's showing the old page content(Links and buttons meant for the Non logged in User).
Caching is obviously good.But how to get rid of this problem ? Do i need to completely remove caching ?
what you want is Partial Page caching:
http://msdn.microsoft.com/en-us/library/ms227429.aspx and http://msdn.microsoft.com/en-us/library/h30h475z.aspx
I ran into the exact same issue and was able to resolve it using Response.WriteSubstitution. Just create a static method that accepts HttpContext as an argument, returns the login status as a string, and render the method using WriteSubstitution:
Response.WriteSubstitution(new HttpResponseSubstitutionCallback(GetLoginStatus));
The rest of the page will cache as normal but the login status will be updated each time the page is loaded.
You can use the VaryByParam directive:
VaryByParam: This attribute allows us
to control how many cached versions of
the page should be created based on
name/value pairs sent through HTTP
POST/GET. The default value is None.
None implies that only one version of
the page is added to the Cache, and
all HTTP GET/POST parameters are
simply ignored. The opposite of the
None value is *. The asterisk implies
that all name/value pairs passed in
are to be used to create cached
versions of the page. The granularity
can be controlled, however, by naming
parameters (multiple parameter names
are separated using semi-colons).
Used like so in the page directive
<%# OutputCache Duration="10800" VaryByParam="State;City" %>
Be careful what you use in the VaryByParam, as this can cause the number of copies of the page in memory to be up to the number of different values of your parameter that exist.
EDIT: as mentioned in comments, this won't work if you're using cookies for login, but some people do use cookie-less login, which puts the info in the GET/POST portion.
See here for more details
I am trying to create some cached user controls. Basically Header and Footer are static.
Except the footer has one link that reads in the URL of the page and puts it into the javascript for sending a link to a friend. So I need that link to be dynamic.
I set up a substitution control and had the static method return the dynamic link.
Go to run and find that substitution controls are not supported at the user control level.
Is there any work around to this? Is there another control like substitution that works on the User Controls that I am not aware of?
I would forget about server side caching in this instance and rely on the simplicity of client side caching.
Your Javascript code could be client side cached just as easily as HTML, either by linking to an external javascript file and adding the necessary headers/expiries, or by embedding the script within the page itself and ensuring the page itself is cached.
Another possible method is by making an Ajax call on the page load to fetch the generated footer complete with correct link. This may take time on the first page load, but subsequent ajax requests would be cached on the client, thus seeing no penalty to future requests.