History API and domain-level urls - javascript

I have two pages on MyDomain.com. The index view which is visible from MyDomain.com/ and MyDomain.com/Foo/Bar. Each view has an ajax call to the other and each one pushes the state using the HTML5 History API.
There are the steps that create the problem:
Start at MyDomain.com/ (Works as expected.)
Click the ajax link to MyDomain.com/Foo/Bar/ (Works as expected.)
Click the ajax link to MyDomain.com/ (Works as expected.)
Click the ajax link to MyDomain.com/Foo/Bar/
Now the URL appears as MyDomain.com/Foo/Foo/Bar/
I don't want a Foo Foo Bar.
My current workaround is to add "../../../" to the front of the URL, but this is inelegant and not foolproof. Another option is a regex expression to count the directory levels.
Is there a better way to get absolute URLs with the History API?
function push(updateElementID, controller, action, url)
{
if (typeof url == "undefined")
{
url = "/" + controller + "/" + action;
}
var state = {
id: updateElementID,
controller: controller,
action: action
}
history.pushState(state, null, url);
}

You may want to ensure that the base element of the href element in the DOM is cleared...at least in the following case, it works for me: On your shared layout page (_layout.cshtml), reset the absolute URL within the DOM by placing the following within the head tags:
<base id="htmldom" href="http://localhost:59805/"/>
of course replacing your port # and on launch, replacing the root URL to the actual domain name.
By doing this, you are setting, or resetting the href property and specifying a base URL for all other relative URLs.
Now would doing it this way would affect any user-input data preserved in the page between back and forward buttons? I'm guessing it would be fine, as the above only resets the href property, and any other info in the DOM should be there.

Related

HttpRequest still gets the old parameter before window.history.replaceState

I have a Sharepoint onprem server side webpart and I would need to replace my query parameter without refreshing the page so I used
if (history.pushState) {
var newurl = "<%=getURL()%>" + "/SitePages/searchresults.aspx?searchtext=" + searchText;
window.history.pushState({ path: newurl }, '', newurl);
}
now this would trigger a button click, and a postback would happen which refreshes the contents of my page without reloading it. it needs to get the query string parameter from the URL. its working when i use
HttpContext.Current.Request.UrlReferrer.AbsoluteUri;
but I am not sure if this is the correct way to do it. and I noticed that in the browser network tab, the xhr call is still the old query parameter before i changed it via pushState.
Is there a way that I can change the URL and capture it in the code behind in asp?

Redirect to different URL when current URL contains some string

I have a requirement wherein I need to redirect my page to a different URL when my current URL contains some string.
For instance,
If my current URL contains www.testdomain.com or www.testdomain.com/web/region then it should redirect to www.testdomain.com/group/region. I tried the below code but it returns "The requested resource could not be found -- https://www.testdomain.com/web/region/testdomain.com/group/region".
$(document).ready(function() {
if (window.location.href.indexOf("web/region") > -1) {
window.location.href=window.location.hostname+'/group/region';
}
})
It is adding the URL twice here. But when I pass the direct URL window. location.href="www.testdomain.com/group/region" it is working.
Can someone guide me on how do I force redirect my page if the URL contains www.testdomain.com or www.testdomain.com/web/region?
Thanks
Start with // so that the browser knows it's not a relative URI:
window.location.href = '//' + window.location.hostname+'/group/region';
You can also prepend the protocol:
window.location.href = window.location.protocol + '//' + window.location.hostname+'/group/region';
It's adding the URL twice because browsers interpret /group/region as a relative path, automatically prepending the current domain UNLESS otherwise specified. (Maybe others can explain why window.location.hostname doesn't immediately return, thus preventing the browser from assuming a relative path?)
Example: If you explicitly set a domain, the browser will redirect to it as expected.
window.location.href='http://www.google.com/'
Otherwise, if you take away "www."
window.location.href='google.com/'
Your browser will redirect to "www.testdomain.com/google.com", appending the string.
The fix is simple.
Just delete window.location.hostname+ and it will only return the URL once.
Or... for a better user experience, I would suggest using window.location.replace() which DOES NOT save the current page in session history.(You don't want to go back, just to be redirected again!)
SOLUTION:
Replace your return block with this.
window.location.replace('/group/region')

Reload a page inside iframe

I have an iframe and I want to reload the currently displayed page on button press.
HTML:
<iframe id="webView"></iframe>
JS:
function reloadPage()
{
var webView = document.getElementById("webView");
//CODE
}
Inside the reloadPage() method I tried different solutions:
Call reload()
webView.contentWindow.location.reload();
This just doesn't work because the pages loaded inside the iframe are from a different domain than the main page.
Set src
webView.src = wevView.src;
It gives wrong result because it contains the initial url that I set to the iframe, non the current one.
Set location
webView.contentWindow.location = webView.contentWindow.location
I was expecting it to not work with urls from different domains (the same as calling reload()), but actually it works and also gives a good result.
Good but not perfect: the location object holds the current url but strips any parameter.
For example if the frame is currently displaying the following url:
http://www.myserver.com/thatsite/?page_id=11
the location object contains this url:
http://www.myserver.com/thatsite/
So this one works well as long as there are no parameters in the url.
Better solution?
I rely heavly on urls with parameters (mostly WordPress installations) so i need a way to keep them while reloading.
Anyone knows a solution to achieve this?
just not possible, see this thread:
Get current URL from IFRAME
and this one
How do I get the current location of an iframe?
Since setting location works, you could use location.search to retrieve the GET parameters and reconstruct the URL that way.
Example:
webView.contentWindow.location = webView.contentWindow.location + webView.contentWindow.location.search

Using window.history.back() to navigate to a certain page?

Is it possible to use window.history.back() to navigate back to a particular page? Like an index.php page? I ask because the way my setup is, some users may have to be directed back 2 pages while others might have to only be directed back one page (depending on more complicated things), but they will all have to be directed back to the same index.php page. So, is this possible?
window.history.go(); let you specify how many pages you want to go back or forward in the browser session history.
https://developer.mozilla.org/en-US/docs/Web/API/History#Methods
If you keep a breadcrumb trail, you'll know the correct number needed… although there might be a better way to do this.
It turns out to be that in chrome particularly in version 105.0.5195.127 the browser appends previous page's url, aka 'https://yourdomain.com/foo/bar' instead of 'https://yourdomain.com/bar' into your next page while pushing state as if
window.history.pushState((null, null, '/bar')
And I suggest to include the full url in order to handle any url case
export async function pushHistoryState(url)
{
try {
console.log('History state URL:' + url);
let loc = `${location.protocol}//${location.host}/`;
window.history.pushState({ prevUrl: window.location.href }, null, loc + url);
} catch(e) {
console.log(e);
}
}
window.history.state.prevUrl now contains previous URL
useful links: https://stackoverflow.com/a/56184390/6897369 Back button / backspace does not work with window.history.pushState How to get the previous URL in JavaScript? Why does my history.pushState call result in a null state? How to add or append new stateObject to history window.history.pushState change url without removing last part window.history.pushState not working for a second time

Click ID and open URL?

I am trying to click on a #ID and open a URL - but [as a newbie] - I can't seem to get it. I am using
$('#Test').click(function() {
OpenUrl('some url');
return false;
});
Something like:
$("#Test").click(function(event){
window.location.href = "some url";
event.preventDefault();
});
Just use window.location = 'some url'
$('#Test').click(function() {
window.location = 'http://www.google.com'
return false;
});
To elaborate a bit, window.location is an object with different quite interesting properties, you can read more about it here. In short, it contains the following properties (quoted from the link):
Property Description Example
hash the part of the URL that follows the #test
# symbol, including the # symbol.
host the host name and port number. [www.google.com]:80
hostname the host name (without the port number www.google.com
or square brackets).
href the entire URL. http://[www.google.com]:80
/search?q=devmo#test
pathname the path (relative to the host). /search
port the port number of the URL. 80
protocol the protocol of the URL. http:
search the part of the URL that follows the ?q=devmo
? symbol, including the ? symbol.
Since window.location is an object, it can also contain methods, which window.location does. By using these methods, instead of just assigning a string to the object, you can exert greater control of how the page is loaded, i.e. force a reload from the server or allow the browser to use a cached entry, skip creating a new history point etc.
Here is an overview of available methods:
Method Description
assign(url) Load the document at the provided URL.
reload(forceget) Reload the document from the current URL. forceget is a
boolean, which, when it is true, causes the page to always
be reloaded from the server. If it is false or not specified,
the browser may reload the page from its cache.
replace(url) Replace the current document with the one at the provided
URL. The difference from the assign() method is that after
using replace() the current page will not be saved in
session history, meaning the user won't be able to use
the Back button to navigate to it.
toString() Returns the string representation of the Location object's
URL.
You can also open resources in new windows if you want to. Please be aware that some users dislike having links opened in new windows for them, and prefer to having to consciously make this decision themselves. What you can do, however, is to mimic some of this functionality in your click-handler and try to figure out which mouse-button was clicked. If it was the middle-mouse button, then most browsers would open the link in a new window. This won't be exactly the same, since users won't be able to right-click and select 'Open in new window', but it might be good enough. Anyway, here's how to open a resource in a new window:
var WindowObjectReference;
function openRequestedPopup()
{
WindowObjectReference = window.open(
"http://www.domainname.ext/path/ImageFile.png",
"DescriptiveWindowName",
"resizable=yes,scrollbars=yes,status=yes");
}
You can read a lot more information here
hm if your OpenUrl function looks anything like this this should work just fine :D
function OpenUrl(url){
window.location = url;
}
btw: why returning false on click??

Categories