Can I get a parameter from shortened URL through an Iframe? - javascript

I have shortened URL's scanned from QRCODES.
The full URL has some parameters that I need.
I'm putting up an Iframe to load the shortened URL and was hoping to get the "full" url once it loaded.
But didn't get to work...
Is it possible?
Once the Iframe is loaded, I try access it using:
iframe.contentWindow.location.href
But always get an error
ERROR DOMException: Blocked a frame with origin "http://localhost:8100" from accessing a cross-origin frame.

There are solutions to the communication between iframe and host if you control the content of both windows, but they often feel like hacks and can be limiting.
For a general solution, you could get the redirected URL before you even load the iframe.
The fetch api has a "redirect" option you can set to "manual" to get the URL it redirects to.
fetch(shorturl, {redirect: "manual"})
.then(function(response) {
var iframeurl;
if (response.type==="opaqueredirect") {
// set to redirected url
iframeurl = response.url
}
else {
// use original url.
iframeurl = shorturl
}
iframe.contentWindow.location.href = iframeurl;
handleQueryString(iframeurl)
})

Related

How to get Previous visited page URL in Javascript? [duplicate]

Is there any way to get the previous URL in JavaScript? Something like this:
alert("previous url is: " + window.history.previous.href);
Is there something like that? Or should I just store it in a cookie? I only need to know so I can do transitions from the previous URL to the current URL without anchors and all that.
document.referrer
in many cases will get you the URL of the last page the user visited, if they got to the current page by clicking a link (versus typing directly into the address bar, or I believe in some cases, by submitting a form?). Specified by DOM Level 2. More here.
window.history allows navigation, but not access to URLs in the session for security and privacy reasons. If more detailed URL history was available, then every site you visit could see all the other sites you'd been to.
If you're dealing with state moving around your own site, then it's possibly less fragile and certainly more useful to use one of the normal session management techniques: cookie data, URL params, or server side session info.
If you want to go to the previous page without knowing the url, you could use the new History api.
history.back(); //Go to the previous page
history.forward(); //Go to the next page in the stack
history.go(index); //Where index could be 1, -1, 56, etc.
But you can't manipulate the content of the history stack on browser that doesn't support the HTML5 History API
For more information see the doc
If you are writing a web app or single page application (SPA) where routing takes place in the app/browser rather than a round-trip to the server, you can do the following:
window.history.pushState({ prevUrl: window.location.href }, null, "/new/path/in/your/app")
Then, in your new route, you can do the following to retrieve the previous URL:
window.history.state.prevUrl // your previous url
document.referrer is not the same as the actual URL in all situations.
I have an application where I need to establish a frameset with 2 frames. One frame is known, the other is the page I am linking from. It would seem that document.referrer would be ideal because you would not have to pass the actual file name to the frameset document.
However, if you later change the bottom frame page and then use history.back() it does not load the original page into the bottom frame, instead it reloads document.referrer and as a result the frameset is gone and you are back to the original starting window.
Took me a little while to understand this. So in the history array, document.referrer is not only a URL, it is apparently the referrer window specification as well. At least, that is the best way I can understand it at this time.
<script type="text/javascript">
document.write(document.referrer);
</script>
document.referrer serves your purpose, but it doesn't work for Internet Explorer versions earlier than IE9.
It will work for other popular browsers, like Chrome, Mozilla, Opera, Safari etc.
If anyone is coming from React-world, I ended up solving my use-case using a combination of history-library, useEffect and localStorage
When user selects new project:
function selectProject(customer_id: string, project_id: string){
const projectUrl = `/customer/${customer_id}/project/${project_id}`
localStorage.setItem("selected-project", projectUrl)
history.push(projectUrl)
}
When user comes back from another website. If there's something in localStorage, send him there.
useEffect(() => {
const projectUrl = localStorage.getItem("selected-project")
if (projectUrl) {
history.push(projectUrl)
}
}, [history])
When user has exited a project, empty localStorage
const selectProject = () => {
localStorage.removeItem("selected-project")
history.push("/")
}
I had the same issue on a SPA Single Page App, the easiest way I solved this issue was with local storage as follows:
I stored the url I needed in local storage
useEffect(() => {
const pathname = window.location.href; //this gives me current Url
localstorage.setItem('pageUrl',JSON.stringify(pathname))
}, []);
On the next screen (or few screens later) I fetched the url can replaced it as follows
useEffect(() => {
const pathname = localstorage.getItem('pageUrl');
return pathname ? JSON.parse(pathname) : ''
window.location.href = pathname; //this takes prevUrl from local storage and sets it
}, []);
Those of you using Node.js and Express can set a session cookie that will remember the current page URL, thus allowing you to check the referrer on the next page load. Here's an example that uses the express-session middleware:
//Add me after the express-session middleware
app.use((req, res, next) => {
req.session.referrer = req.protocol + '://' + req.get('host') + req.originalUrl;
next();
});
You can then check for the existance of a referrer cookie like so:
if ( req.session.referrer ) console.log(req.session.referrer);
Do not assume that a referrer cookie always exists with this method as it will not be available on instances where the previous URL was another website, the session was cleaned or was just created (first-time website load).
Wokaround that work even if document.referrer is empty:
let previousUrl = null;
if(document.referrer){
previousUrl = document.referrer;
sessionStorage.setItem("isTrickApplied",false);
}else{
let isTrickApplied= sessionStorage.getItem("isTrickApplied");
if(isTrickApplied){
previousUrl = sessionStorage.getItem("prev");
sessionStorage.setItem("isTrickApplied",false);
}else{
history.back(); //Go to the previous page
sessionStorage.setItem("prev",window.location.href);
sessionStorage.setItem("isTrickApplied",true);
history.forward(); //Go to the next page in the stack
}
}

Trying to redirect Chrome to new URL using Chrome extension

I am just starting out writing chrome extensions.
y first project: For certain sites, if you click on the extension, the extension will redirect Chrome to the current domainName/archive.
I am using chrome.tabs.update(); to redirect.
If I try to redirect to a hard-coded URL such asYahoo.com, it works correctly.
However, if I try to redirect so what I really want, such as developer.google.com/archive (which I know does not exist), the resulting URL Chrome tries to fetch is:
chrome-extension://injepfpghgbmjnecbgiokedggknlmige/developer.chrome.com/archive
Chrome is prepending the extension's ID to the URL for some reason?
In my background.js, I have the following:
chrome.runtime.onMessage.addListener(function(request, sender) {
chrome.tabs.update( {url: request.redirect});
I got the code above from this article.
Someone else had the same issue here (but not answered)
The full options.js is:
function createButton () {
chrome.tabs.getSelected(null, function(tab) {
var url = new URL(tab.url);
var domain = url.hostname;
archiveURL = domain + "/archive";
let page = document.getElementById('buttonDiv');
let button = document.createElement('button');
button.addEventListener('click', function() {
chrome.runtime.sendMessage({redirect: archiveURL}); // works if I send "Yahoo.com"
});
button.textContent = "> " + archiveURL; // So I know I am sending the right URL
page.appendChild(button);
})
}
createButton();
SUMMARY:
If I set:
archiveURL = "http://sundxwn.tumblr.com/archive";
the system correctly goes to http://sundxwn.tumblr.com/archive.
But... if I set
archiveURL = domain + "/archive";
and confirm that the button text shows: http://sundxwn.tumblr.com/archive,
Chrome tries to go to: chrome-extension://injepfpghgbmjnecbgiokedggknlmige/sundxwn.tumblr.com/archive
Any help would be truly appreciated.
url.hostname is just that, the hostname. For the original URL https://example.com/some/path, it would be example.com.
Then, your constructed URL is example.com/archive. It does not start with a protocol (e.g. http://) or a slash, so it's interpreted as a relative URL to the current page's URL.
And you are calling this from some extension page, e.g. page.html or the auto-generated background page. Its URL is, for example:
chrome-extension://injepfpghgbmjnecbgiokedggknlmige/page.html
So, to construct an absolute URL from a relative URL, Chrome chops that path off at the last slash and adds your relative part.
You need to specify the protocol so that Chrome understands it's a URL that has nothing to do with the current document. And url.origin does that, it would be https://example.com, which then is properly interpreted.

Print a form from another link on clicking a button

I'm trying to figure out how to print an image from another web page link on clicking a button.
I know window.print() but how could I specify the other link I want to print the image from?
Same domain
If the page you wish to print is from the same domain as the iframe's parent then MDN has a good example of how to do this.
You should create a hidden iframe, load your page in it, print the iframe contents and then remove the iframe.
JavaScript:
function printURL( url ) {
var frame = document.createElement( "iframe" );
frame.onload = printFrame;
frame.style.display = 'none';
frame.src = url;
document.body.appendChild(frame);
return false;
}
function printFrame() {
this.contentWindow.__container__ = this;
this.contentWindow.onbeforeunload = closeFrame;
this.contentWindow.onafterprint = closeFrame;
this.contentWindow.focus(); // Required for IE
this.contentWindow.print();
}
function closeFrame () {
document.body.removeChild(this.__container__);
}
HTML:
<button onclick="printURL('page.html');">Print external page!</button>
Cross domain
If the page you wish to print is from another domain then your browser will throw a Same-Origin Policy error. This is a security feature that forbids scripts accessing some data from different domains.
To print cross domain content you will need to scrape the page's source and load it into the iframe. The browser will then believe that the iframe's content comes from your domain and won't hiccough when you try to print.
However, if you try to do this in the frontend, this just pushes the problem back one step further, as the same-origin policy also won't let you scrape content from another domain in this way. But the same-origin policy for data scraping is the equivalent of tying a bull up with cotton thread - it doesn't really hold you back - so this hurdle is easily circumvented. You can either write your own backend script (in PHP or your choice of language) that will scrape the content and deliver it to your page, or you can use any one of a number of web services that already do this. https://multiverso.me/AllOrigins/ is as good as any, it doesn't require backend programming, and it's free so I'll use that in this example.
Using Jquery, the modified printURL function from above would be:
function printURL( url ) {
var jsonUrl = 'http://allorigins.me/get?url=' + encodeURIComponent(url) + '&callback=?';
// the url / php function that allows content to be scraped from different origins.
$.getJSON( jsonUrl, function( data ) {
// get the scraped content in data.content
var frame = document.createElement( "iframe" ),
iframedoc = frame.contentDocument || frame.contentWindow.document;
frame.onload = printFrame;
frame.style.display = 'none';
iframedoc.body.html( data.contents );
document.body.appendChild(frame);
}
return false;
}
The other functions from above would remain the same.
Note that if the page you're printing is built using AJAX calls or is significantly styled with scripting then the iframe may print something that looks quite unlike what you were expecting.

How can I get the previous URL of a tab?

When writing a Chrome extension, given a tab, how can I get the URL of the previously-visited page in that tab? i.e. the url that will appear in the omnibar after I hit "back"?
Since I could not find any API approach, I just applied vux777's suggestion above: every time a page loads I store a mapping from its id to its URL. Then when I want to find the previous page of a tab, I can search for it there.
So, storage:
chrome.webNavigation.onCommitted.addListener(function (data) {
if (data.frameId !== 0) {
// Don't trigger on iframes
return;
}
var tabIdToUrl = {};
tabIdToUrl[data.tabId.toString()] = data.url;
chrome.storage.local.set(tabIdToUrl);
});
And retrieval:
chrome.storage.local.get(tabId, function (item) {
var url = item[tabId];
...
});
I am running into the same issue, really wished that chrome api could return both the before and after url at chrome.tabs.onUpdated event.
My solution is similar to #Oak, but instead of using chrome.storage.local I am using Window.sessionStorage due to the following two reasons:
chrome.storage.local behaves similarly to Window.localStorage, it persists even when the browser is closed and reopened. If you don't do cleanup yourself, your local storage will grow overtime with a lot of redundant information. With session storage, whenever you closed all of your browser instances (end of persistent background page's lifetime). it will conveniently forget everything :)
Window.sessionStorage stores data in strings only, which is good for this use case (tab.url), chrome.storage.local is a more powerful tool, you can save some space when you want to store objects.
my test case is something like this:
chrome.tabs.onUpdated.addListener(function(tabId,changeInfo,tab){
var newUrl = changeInfo.url;
if(newUrl){
window.sessionStorage[tabId] = newUrl;
}
});
Another approach uses the referrer of the page. This requires that:
there must be some way to retrieve the page referrer, either by loading a content script into the page that communicates the referrer to the extension, or by somehow inspecting the web navigation or request as it is happening in the background script to retrieve the Referer header (notice the typo)
the page that referred to the current page must have a referrer policy that provides sufficient information
content-script.js
// notify extension that a page has loaded its content script, and send referrer
chrome.runtime.sendMessage({ referrer: document.referrer });
background.js
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
console.log(sender.tab.id);
console.log(request.referrer);
});
Alternatively, the extension could query a tab to get its referrer. You must ensure the tab is ready (has a loaded content script):
content-script.js
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
sendResponse({ referrer: document.referrer });
});
background.js
function askTabForReferrer(tabId) {
chrome.tabs.sendMessage(tabId, {}, function(response) {
console.log(response.referrer);
});
}
const exisitingTabWithLoadedContentScriptId = 83;
askTabForReferrer(exisitingTabWithLoadedContentScriptId);

How to use Javascript's getElementById on another page

I'm able to use document.getElementById() fine when working with the same page, but I haven't been able to figure out how to get the element by it's ID from a different page. So far, my guess has been to use jQuery's $.get function, which I haven't gotten to work either.
$(function() {
$('#inputform').submit(function(e) {
e.preventDefault();
var rawnum = $('#inputform').serialize();
var num = rawnum.split("=")[1];
var url = "http://google.com/"; //this url is an example
$.get(url, function(data, status) {
$("html").html(data);
});
});
});
Your page would need to be the opener and the other page and, more importantly, the two pages would have to be served by the same origin (see same origin policy) or that other page would have to be served with CORS headers precising this access is authorized.
As your example shows, this is obviously not the case so you simply can't access the element.

Categories

Resources