Prevent iframe from adding browser history - javascript

I have an angularjs app running within a third party iframe (i.e. different domains). All the routing and navigation within this app will add entries to the browser history, but I'd like to disable this app from do so. After much research, it seems that making use of the html5 history api is my best chance at this.
This reference makes use of a solution which essentially, onclick of a link within an iframe, will replace the current history state (history.replaceState()) with that of the links destination url. Thus the browser will not add a history entry if the current url is the same as the destination: http://www.webdeveasy.com/back-button-behavior-on-a-page-with-an-iframe/
I'm trying to implement a similar solution within an angular context which uses the ngRoute module for all navigation. With that said, I think adding a handler for the $routeChangeStart event is one solution, but it doesn't work:
$rootScope.$on('$routeChangeStart', function(e, cur, pre) {
history.replaceState(null, null, $location.absUrl());
});
In the above, this event handler appears to execute prior to navigation taking place. The absUrl is a path within the iframe app, and is the destination of the route, however the browser is still adding entries. Any ideas why?
EDIT:
So I found a partial solution. Much of the app navigates using $location.path(myPath). If I add replace() onto the $location.path() then this tells the browser to replace the history entry instead of adding a new one.
This seems to work for all navigation which makes use of $location.path(), but not for user driven navigation (i.e. clicking links); I need to find a solution for those scenarios.

Related

Manipulate browser history in Cypress

I'm using Cypress for integration testing. On the page I have added "Back" button. I want to test, that when I click that button, the browser displays the previous page. I'm looking for a way to add some url in browser history from Cypress. This way, I'll click the button, I'll check that corresponding page is rendered and that's all. Is there any way from Cypress to manipulate browser history? For example like:
cy.history.push(newUrl);
or something?
Seems like we can use native JS API to add URL in the history.
Here is the reference of similar issue and how to use pushState
cy.window().then((win) => {
win.history.pushState(...)
})
// or
cy.window().its('history').invoke('pushState', ...)

How to Prevent refreshing the page moves to root page in ionic 2/3

I am creating more pages in ionic 2, when i refresh the page it always redirect to the root page index, how to prevent it.
Example:
I created login page and welcome page after logging in if i press refresh it automatically moves to root page as login.
When you create a project using ionic-CLI usually you have a in src/app/app-component.ts a variable called rootPage: any = 'HomePage';
This is your root page. If you want to change to go to your AuthPage
rootPage: any = 'AuthPage';
Here AuthPage is the name of the class of your authpage
This behavior is typically observed when you are testing locally (through ionic serve command). I noticed that this should not be the case after deployment to a server. Have you tried doing that and testing it again?
i've manage to find some solution that solve this problem.
As i know and under my understand the ionic framework use the navcontroller state(push, pop) to navigate the page then if we refresh the browser this navcontroller state will gone and then go to the root.
So the solution that i've found is in this Question from stack overflow also. the answer give you 2 choices "LazyLoad" and "Deeplink"
But ive manage to solve my solution with "LazyLoad" Method by given custom ionic page segment name that different from the default. for more informantion is here

Remove hash from URL, load the page at hash-less URL, then add hash to URL without reloading the page

I'm working on a website that uses AJAX loading with some jQuery animations.
With JavaScript, I grab the href from a dynamically generated link to a PHP-based page, and then add that href to URL (after the inevitable #/) .
So far so good, except if a user bookmarks the page and tries to access it, that user will arrive to the home page, instead of the page he/she expected to access.
So, when a page is accessed directly, not by clicking on the internal link of the website, I want to remove #/ from the url, but keep everything after it, so that URL that was bookmarked like this:
http://www.mysite.com/#/somepage
gets rewritten as this:
http://www.mysite.com/somepage
THEN, after the proper page ( http://www.mysite.com/somepage ) finished loading, I want to stick #/ back into its former place in URL ( http://www.mysite.com/#/somepage ), without reloading the page (which, thanks to a clever snippet I'm using, will ensure that the rest of the navigation works the way it should.)
So:
Before page loads, check URL and if it has #/, remove it.
Load page located at hash-less url
Redisplay the url with #/, without reloading the page.
Is it even doable? If yes, I'd be grateful for a lesson.
What you are trying to do is doable but an utter PITA to maintain, and it will not be available on all browsers. That aside, the key resides in the history object relatively recently extended to add a new set of "tricks". Its full doc is available from MDN.
What you are after to do this is the replaceState command. Reads as follows:
Updates the most recent entry on the history stack to have the specified data, title, and, if provided, URL. The data is treated as opaque by the DOM; you may specify any JavaScript object that can be serialized. Note that Firefox currently ignores the title parameter; for more information, see manipulating the browser history.
This will allow you to replace your current page in the history of the browser, but not in the URL. The URL will be exactly as you have it - with the hash. No point changing it considering your solution.
However, you will have to make sure that your hashless page redirects to the hash-present page for clients with the history object, for consistency. That's the only requirement.
Before page loads, check URL and if it has #/, remove it.
Not possible. The fragment id is not sent to the server, so you can only access it with client side code and that requires the page to load (or at least to start loading).
Load page located at hash-less url
Redisplay the url with #/, without reloading the page
Use XMLHttpRequest to get the data, DOM to change the document to use it, and the history API to change the URL in the address bar.
As has been pointed out in one of the answers, you can't remove hash before your page loads.
However, once the page started loading, the manipulation described in the question is possible.
Here's one way to do it.
// Remove the hash and reload the page at url without hash
if (window.location.href.indexOf('/#/')>=0) {
window.location = window.location.href.replace(/\/#\//, '/');
}
Once the new page started loading, you can use history.pushState to update the URL display:
if ((window.location.href.indexOf('/#/')<1) && (location.pathname != "/")) {
history.pushState({}, "page x", location.protocol + '//' + location.host + '/#' + location.pathname);
}
You gotta keep in mind though that pushState is only available for browsers started with Gecko 2.0, so placing the hash back into the url will not work in older browsers, period.
This may lead to some unfortunate situations. For example, hypothetically, your url http://www.mywebsite.com/somepage gets indexed by a search engine. A user clicks on that link, accessing your website in an older browser that doesn't support pushState, and then clicks on some other link when browsing your AJAX-enabled website. That user is likely to arrive to
http://www.mysite.com/somepage/#/someotherpage
And then, as the user keeps clicking, it will only keep getting worse:
http://www.mysite.com/somepage/#/someotherpage/#/yetanotherpage/#/andsoon/#/andsoforth/
So what you probably need is something to make sure that your hashes don't keep propagating.
You can also wrap your hash removing / replacing code in a conditional:
if (history.pushState) {
// add hash
} else {
// provide some alternative
}
Finally, look into these two resources. You may not need the hash at all: History.js and jQuery Address.

PrimeFaces ViewExpiredException after page reload

I have wrapper PrimeFaces.ajax.AjaxResponse to handle ViewExpiredException (reloading the page):
var handleViewExpired = function (viewId) {
window.alert('${msg.ajax.viewExpired}');
window.location.reload();
};
However, sometimes I got that error over and over again after trying to click anything invoking AJAX requests on the site:
javax.faces.application.ViewExpiredException: /tree.xhtmlNo saved view state could be found for the view identifier: /tree.xhtml
at org.apache.myfaces.lifecycle.RestoreViewExecutor.execute(RestoreViewExecutor.java:128)
Am I doing refresh in wrong way? What should I do to invoke full page reload, such as clicking reload in browser? Do I need to remove cookies (JSESSIONID, oam.Flash.RENDERMAP.TOKEN)?
I'm using PrimeFaces 3.5 with MyFaces 2.0.7 running on WebSphere 7.0.
If you have many (>15) pages/views/frames that are concurrently opened in the session, then, the following may be useful.
You need to have a look on:
1. numberOfViewsInSession: defines the number of (top-level) view states (pages) to support back button operation
2. numberOfLogicalViews: defines the number of logical views (frames) that can present in a page (per top-level view)
A quick action to make sure if it's relevant is to set those numbers to 500, and see
If they are relevant, then, you can find more information in the following links:
http://www.java.net/node/681211
Problem with numberOfViewsInSession and multiple tabs

Change url via JavaScript (no hash-tag)

I'm wondering how does facebook change the url when I switch between pictures in a album? There is no hash-tag, just a real url.
Example:
The current url: facebook.com/photo.php?fbid=XXXXXX1 and if I click next, the url changes to facebook.com/photo.php?fbid=XXXXXX2
Does anybody know how to realize this with JavaScript?
Yes. Check out https://developer.mozilla.org/en/DOM/Manipulating_the_browser_history#Adding_and_modifying_history_entries
It pushes a new history state (an HTML5 thing) instead of using the hash key.
My first hunch would be:
document.location = facebook.com/photo.php?fbid=XXXXXX2;
With some way of preventing the default reload page action.
Summerizing all the answers,
we can say (I'm not a FB coder) that Facebook uses:
the HTML5 window.history.pushState / replaceState / popState methods on browser that support these methods (I think one is Chrome). In this way Facebook changes the real url (not just the part after the # character).
On other browsers, that do not support these new HTML5 methods (like IE6 / IE7 and IE8), Facebook simply changes the part of the url after the # character, by simply setting the the window.location.hash property.
On my tests, it only changes the hash tag:
E.g. the real URL is:
http://www.facebook.com/photo.php?fbid=x&set=z
and clicking next results in:
http://www.facebook.com/photo.php?fbid=x&set=z#!/photo.php?fbid=y&set=z&pid=pid&id=id
The part after the hash is setup for Google AJAX crawl. But for the purpose of the browser, it's just a hash (fragment identifier).

Categories