I've written a Chrome extension that replaces the new tab if the user wants that. It works by intercepting tabs.onUpdated and redirecting chrome://newtab/ to another page from the extension, as described in this answer.
The problem is that the address bar of that page keeps the (ugly) URL of the HTML within the extension, e.g. chrome-extension://hibkhcnpkakjniplpfblaoikiggkopka/html/newtabl.html. How can that URL be replaced with the empty string?
I've tried history.replaceState, but the best that can do is to change the file (newtab.html) in the path. Using an http:// URL crashes the extension:
history.replaceState({}, 'iDoRecall practice', 'http://type-anything-here.com');
Any clever way to clear the Omnibox?
Put simply, History API can only change the path part of the URL, not the origin (protocol://host:port) for an obvious reason of preventing site fraud:
If the origin of the resulting absolute URL is not the same as the origin of the responsible document specified by the entry settings object, and either the path or query components of the two parsed URLs compared in the previous step differ, throw a SecurityError exception and abort these steps. (This prevents sandboxed content from spoofing other pages on the same origin.)
The omnibox may be empty only in one case: on a new tab page, that is you'll have to replace the new tab in manifest.json in chrome_url_overrides.
Related
I want my extension to change the document.referrer of certain webpages, but searching for this leads to documentation on how to change the Referrer in the HTTP request headers.
Is there any way to use an extension to change document.referrer, preferably before the javascript(s) of a webpage loads?
Currently I refresh pages where I want the document.referrer altered with window.location.replace(window.location.href), but this generates a noticeable flicker, and only can change the referrer to the current page.
override.js:
Object.defineProperty(Document.prototype, 'referrer', {
get() {
return 'foo';
},
});
This should be put in page context at document_start, there are several methods.
For ManifestV3 the most reliable method is registerContentScripts: example. Specify the correct pattern in matches and optionally add allFrames: true; matchOriginAsFallback: true if the site uses frames.
Note that due to a bug in Chrome the sites can extract the original getter and call it on the main document to get the real referrer. The workarounds are mentioned in the report and aren't simple.
I am a beginner in working with Cypress.
I am trying to build one test scenario for login.
I have this first url defined in cypress.json which is the page for signing in:
"cozone_url": "https://idp-develop-devdb.staging.cozone.com/"
After successfully logging in, I am taken to the second page with URL: https://portal-develop-devdb.staging.cozone.com/ui/#/. In this page, I have one element which by clicking on it takes me to the actual application that I need to automate:
If I do not remove target attribute for the app element, the application opens correctly on a new child tab. I know that this is not handled with cypress so I tried to remove it:
And ('I Click on Azets Invoice icon', ()=> {
//this should open url https://invoice.test.azets.com/en
cy.get("a[data-test-application-identifier='EFLOW_INVOICES_V2']").invoke('removeAttr','target').click() })
A new tab is not opened, but the https://invoice.test.azets.com/en is not loaded in the original tab and I have this error:
Refused to frame '' because it violates the following Content Security Policy directive: "frame-src
Also, when trying to go directly to the url with visit method I have this error:
The new URL is considered a different origin because the following parts of the URL are different
I know that this happens because of the security restrictions, that Cypress does not allow to change the domain within the same test, but how can I automate this scenario?
I login from url 1, then a page is opened where I have the link to my app and have to click on it and go to url2, which I am not allowed.
I tried to split this into 2 tests and use Cypress.Cookies.preserveOnce() method, but I don't know which cookie name I should preserve for the second test.
Do you have any idea on how should I automate the scenario using Cypress?
Try turning off web security to remove CORS restrictions.
In cypress.json add
{
"chromeWebSecurity": false
}
Ref: Web Security
I am working on a C# MVC website, and have a popup that redirects its parent with a window.parent.location=newRelativePath statement in JavaScript (and then calls a custom method to hide the popup).
In one place in my application, the redirection works great. The browser adds the correct protocol, host and domain at the start of the relative URL that I pass in, and navigates correctly. In another place in my application, the EXACT SAME CALL (i.e. newRelativePath is the same, being called from a popup, parent window has a URL that follows the same kind of format) doesn't work because the browser not only adds the protocol, host and domain, but also adds the controller name from the path of the prior page at the start of the URL (I get a 404 error saying the url "/domain/oldcontroller/newcontroller/action" cannot be found)
In both cases, my original parent window URL is in the format "protocol://host/domain/controller/action/id?querystring", and newRelativePath is in the format "controller/action?querystring"
I don't see any difference in the format of window.location or window.parent.location at the different spots in the application, but something must be different since the browser treats the relative URL I feed in differently - any ideas what that might be?
Thanks very much for your assistance!
Instead of using something like this:
newcontroller/action
You have to use this:
/newcontroller/action
The slash / at the beginning is important to tell the explorer is not a relative path, but an absolute path.
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.
The code below works well. Here is my problem: The window url redirects, but the original url is not logged in my browser history.
For example, if I visit "http://example.com/page1", the browser redirects to "http://example.com/test", as it should. However, I need the original url visited ("http://example.com/page1") to show up in my browser history so that I can call upon it in a different function.
Is there anyway to get the original url visited to log in my browser's history before redirecting?
<!-- script to enable age verification cookies and ensure people have age checked -->
<script type="text/javascript">
$(document).ready(function(){
if (window.location =="http://example.com/home") {//do nothing
} else {
window.location = "http://example.com/test";
}
});
</script>
I think what you need is window.location.href. This adds the previous URL to the browser history.
I came across this behavior myself and it was because I was loading pages into chrome via the filesystem, i.e. using the file:// protocol. I started an HTTP server, and using that got it to keep the history.
tl;dr, just show me the code
var newUrl = "https://example.com.page2";
// Navigate to newUrl, adding a new entry to the Browser History
window.location.assign(newUrl);
window.open(newUrl, "_top");
JavaScript Browser Navigation With History
There are at least two methods to navigate (redirect) while retaining browser history. With Vanilla JavaScript, one of these are likely what we're looking for:
Easiest: window.location.assign() - part of the Location object in the Browser Window API.
Most Powerfull: window.open() - part of the Browser Window API. window.open() is far more powerful than location.assign() - as it can affect not just the current browser tab, but can also be used within an <iframe>, control which browsing context (a tab, window or iframe) to control, as well as change window features - including options such as the window's default size and position, whether to open a minimal popup window, and so forth.
Keep in mind that window.open() has caveats and usability/user experience issues, as it can open Popups - the exact same popups that most browsers block (Chrome, Firefox) because advertisers / spammers abuse(d) the functionality provided by window.open(). It's still a viable API to use, when used properly.
Browser History can also be managed and controlled directly via the Browser History API, including reading from, modifying existing, and adding new history entries. The History API however does not control navigation, and cannot be used for redirection. It's very often used with Single Page Applications, such as AngularJS, React, Vue.js, Svelte, etc.
Most of the text / descriptions below are directly sourced from MDN Web Docs. Please see the included links for more information. I have slightly modified the descriptions and examples from the MDN API Reference to be more relative to the question asked.
window.location.assign()
Source / Reference: https://developer.mozilla.org/en-US/docs/Web/API/Location/assign
The window.location.assign() method causes the window to load and display the document at the URL specified. After the navigation occurs, the user can navigate back to the page that called window.location.assign() by pressing the "back" button.
If the assignment can't happen because of a security violation, a DOMException of the SECURITY_ERROR type is thrown. This happens if the origin of the script calling the method is different from the origin of the page originally described by the Location object, mostly when the script is hosted on a different domain.
If the provided URL is not valid, a DOMException of the SYNTAX_ERROR type is thrown.
window.location.assign() Syntax
window.location.assign(url)
window.location.assign() Parameters
url: Is a string containing the URL of the page to navigate to.
window.location.assign() Example
var newUrl = "https://example.com.page2";
// Navigate to newUrl, adding a new entry to the Browser History
window.location.assign(newUrl);
window.open()
Source / Reference: https://developer.mozilla.org/en-US/docs/Web/API/Window/open.
⚠️ NOTE: I've only included a VERY small amount of information related to the extremely versitile window.open() method. I highly recommend you review the full documentation for window.open().
The open() method of the Window interface loads a specified resource into a new or existing browsing context (that is, tab, window, or <iframe>) under a specified name.
window.open() Syntax
open()
open(url)
open(url, target)
open(url, target, windowFeatures)
window.open() Parameters
url: Optional
A string indicating the URL or path of the resource to be loaded. If an empty string ("") is specified or this parameter is omitted, a blank page is opened into the targeted browsing context.
target: Optional
A string, without whitespace, specifying the name of the browsing context the resource is being loaded into. If the name doesn't identify an existing context, a new context is created and given the specified name. The special target keywords, _self, _blank, _parent, and _top, can also be used.
This name can be used as the target attribute of <a> or <form> elements.
windowFeatures: Optional
A string containing a comma-separated list of window features in the form name=value — or for boolean features, just name.
⚠️ NOTE: See the window.open() syntax for the full reference of Window Features.
window.open() Return value
A WindowProxy object. The returned reference can be used to access properties and methods of the new window as long as it complies with Same-origin policy security requirements.
window.open() Description
The Window interface's open() method takes a URL as a parameter, and loads the resource it identifies into a new or existing tab or window. The target parameter determines which window or tab to load the resource into, and the windowFeatures parameter can be used to control the size and position of a new window, and to open the new window as a popup with minimal UI features.
Note that remote URLs won't load immediately. When window.open() returns, the window always contains about:blank. The actual fetching of the URL is deferred and starts after the current script block finishes executing. The window creation and the loading of the referenced resource are done asynchronously.
window.open() Basic Example
For answering the question, the minimal form of window.open() to browse to a new URL, in the same browser tab, retaining browser navigation history.
var newUrl = "https://example.com/page2";
// Navigate to newUrl, adding a new entry to the Browser History
window.open(newUrl, "_top");