Displaying a specific page of PDF inside iframe in Asp.net - javascript

I have an ASP.NET C# application. I am displaying a PDF file at a specific page inside an iframe. I need to display a specific page of PDF based on a text box value. How can I achieve this ?
The iframe code looks like this:
<iframe runat="server" id="lobjPDFObj" height="600" width="800" > </iframe>
and following is the the details of the text box
<asp:TextBox ID="txtTo" runat="server" Text="1" class="page_txtbox" onfocus="synchronizePDF(this);" ></asp:TextBox>
Details of javascript function
function synchronizePDF(Field) {
//parent.document.getElementById('lobjPDFObj').setCurrentPage(Field.value);
var childiFrame = parent.document.getElementById('lobjPDFObj');
var URL = childiFrame.contentWindow.location.href;
//var URL = childiFrame.src;
var pos = URL.indexOf('#page');
if (pos < 0) pos = URL.length;
var result = URL.substring(0, pos);
if (URL != 'about:blank') {
result += '#page=' + Field.value;
}
childiFrame.contentWindow.location.reload(true);
childiFrame.contentWindow.location.href = result;
//childiFrame.src = result;
//parent.document.getElementById('lobjPDFObj').setAttribute("src", result);
}
But this is not working. It is giving error at "childiFrame.contentWindow.location.href" as The frame requesting access has a protocol of "http", the frame being accessed has a protocol of "https". Protocols must match.
How can i get rid of the error? And i am passing page no as a paramter in the url. How can i show the new page without refreshing entire content?

As stated here: The frame requesting access has a protocol of "https", the frame being accessed has a protocol of "http". Protocols must match and here: Error trying to access a iframe in JavaScript the iframe can show content from other side, but you cannot change it in any way, because it would cause security risk. If you want to change the content of the iframe it source must come from same domain (refer to CORS for more reference).
Another way is to allow Cross-Origin Resource Sharing for other domains. In order to do that you need to specify special header:
Access-Control-Allow-Origin: https://www.test-doc.com
More info about this topic: http://enable-cors.org/server_aspnet.html, http://docs.asp.net/en/latest/security/cors.html.

In both methods shown below, a local PDF is opened in an iframe, at the selected page number, when the focus leaves the TextBox.
Method 1
In this method, the iframe source URL is set in two steps. The first step resets the source, the second sets it to the actual URL. This second step has to be performed asynchronously in order to work (here with the help of setTimeout).
The markup for the iframe and the TextBox:
<iframe id="iframePdfViewer" name="iframePdfViewer" width="700px" height="700px" ></iframe>
<asp:TextBox ID="txtPageNumber" runat="server" Text="1" onchange="showPDF(this.value);" />
The Javascript function:
function showPDF(pageNumber) {
var iframe = document.getElementById("iframePdfViewer");
iframe.src = '';
setTimeout(function () { iframe.src = 'MyFolder/MyDoc.pdf#page=' + pageNumber }, 0);
}
Method 2
In this method, the iframe is replaced by a new one each time a new page of the PDF is to be displayed. In order to reduce screen flicker: (1) the new iframe is inserted under the old one, and (2) the old iframe is removed only when the new one is fully loaded.
The markup:
<div id="divPdfViewer" style="position: relative; width: 700px; height: 700px;"></div>
<asp:TextBox ID="txtPageNumber" runat="server" Text="1" onchange="showPDF(this.value);" />
The Javascript code:
function showPDF(pageNumber) {
var divPdfViewer = document.getElementById('divPdfViewer');
var ifrm = document.createElement("IFRAME");
ifrm.id = 'iframePdfViewer';
ifrm.style.position = 'absolute';
ifrm.style.width = '100%';
ifrm.style.height = '100%';
var oldPdfViewer = divPdfViewer.firstChild;
if (oldPdfViewer) {
ifrm.onload = function () { divPdfViewer.removeChild(oldPdfViewer); };
// Replace the line above by the line below if support for IE is required
// setTimeout(function () { divPdfViewer.removeChild(oldPdfViewer); }, 100);
divPdfViewer.insertBefore(ifrm, oldPdfViewer);
}
else {
divPdfViewer.appendChild(ifrm);
}
ifrm.setAttribute("src", 'MyFolder/MyDoc.pdf#page=' + pageNumber);
}

Related

How to get the current page url from iframe and display on the browser

i have two domains. One for selling products that is https://sellproducts.com and the other for product documentation that is https://docs.product.wiki
In https://sellproducts.com i have page called docs ( https://sellproducts.com/docs) which i used iframe to call or display contents from https://docs.product.wiki
<iframe id="docs" src="https://docs.product.wiki/" frameborder="0">
</iframe>
The https://docs.product.wiki have many pages example,
https://docs.product.wiki/intro.html
https://docs.product.wiki/about.hml
i want to use javascript or jquery to get the current url from iframe and display it in the browser like " https://sellproducts.com/docs?page=intro", when a page is clicked on or reloaded.
If you can put some js on both side it's possible.
In order, there the logic you needs:
Create/Get iframe element -> document.createElement
Parse URL -> URLSearchParams
Catching click event on iframe's link -> createEventListener
Manage main window location -> window.top and window.location
Following could be a good start:
On your https://sellproducts.com/docs put this code:
window.onload = function(e) {
const docsUrl = 'https://docs.product.wiki/';
const queryString = window.location.search; //Parse URL to get params like ?page=
let iframe;
if(document.querySelector('iframe').length) //If iframe exit use it
iframe = document.querySelector('iframe');
else
iframe = document.createElement('iframe'); //Create iframe element
iframe.src = docsUrl; //Set default URL
iframeframeBorder = 0; //Set frameborder 0 (optional)
if (queryString !== '') {
const urlParams = new URLSearchParams(queryString); //Convert to URLSearchParams, easy to manipulate after
const page = urlParams.get('page'); //Get the desired params value here "page"
iframe.src = docsUrl+page + '.html'; //Set iframe src example if ?page=intro so url is https://docs.product.wiki/intro.html
}
if(!document.querySelector('iframe').length)
document.body.appendChild(iframe);//Append iframe to DOM
}
And the https://docs.product.wiki side put this code in your global template (must be on all pages):
let links = document.querySelectorAll('a'); //Get all link tag <a>
links.forEach(function(link) { //Loop on each <a>
link.addEventListener('click', function(e) { //Add click event listener
let target = e.target.href; //Get href value of clicked link
let page = target.split("/").pop(); //Split it to get the page (eg: page.html)
page = page.replace(/\.[^/.]+$/, ""); //Remove .html so we get page
let currentHref = window.top.location.href; //Get the current windows location
//console.log(window.location.hostname+'/docs?page='+page);
window.top.location.href = 'https://sellproducts.com/docs?page='+page; //Set the current window (not the frame) location
e.preventDefault();
});
});
Feedback appreciated :)

Submit text value into iframe input

I want to send a text value from the parent page to the iframe < input >. It's all on the same domain and folder.
Was trying this code:
function addNick(nick) {
var txt = parent.document.getElementById('input').value;
parent.document.getElementById('mess').value = 'to[' + nick + '] ' + txt;
parent.document.getElementById('mess').focus();
}
<iframe src="input.php" name="input" id="input" scrolling="auto"></iframe>
Text is triggered in mess.php to be submitted with link to the above iframe input.
name
which is printed in index.php with js
$(document).ready(function(){
setInterval(function(){//setInterval() method execute on every interval until called clearInterval()
$('#load_posts').load("mess.php").fadeIn("slow");
//load() method fetch data from mess.php page
}, 1000);
});
So basically the addNick code won't work.
Any help will be much appreciated.
FINAL SOLUTION
function addNick(nick) {
var iframe = document.getElementById('iframe');
//the element you want to target:
var mess = iframe.contentWindow.document.getElementById("mess").value += `${nick}, `;
}
So first get the iframe element by id, then target the element within the iframe..
so if input.php has an <h1></h1> tag this will set the innerHTML to what the parameter nick holds..
function addNick(nick) {
var iframe = document.getElementById('iframe');
//the element you want to target:
var mess = iframe.contentWindow.document.getElementsByTagName("H1")[0];
mess.innerHTML = `to ${nick}`
}
On how to access dom of iframe, check out this example:
https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_element_iframe

Iframe src attribute change with parameter

I’m trying to change the src attribute of an <iframe> depending if the iframe src has /?foo or not.
I had this solution:
<script>
jQuery(document).ready(function($) {
$('iframe[src*="?foo"]').each(function() {
$('#frame').attr('src', "http://www.example.com/page2");
});
});
</script>
<iframe id="frame" src=„www.example.com/page1/?foo"></iframe>
But my problem is that I have no access to the page, where the iframe is emded so I can't write this code into the <head> of the site.
I have access to both pages www.example.com/page1 and www.example.com/page2
I don’t know how I need to change the code to manipulate the src.. I am not sure if this is even possible, when I have no access to the page with the iframe
As seen in How to retrieve GET parameters from javascript? you can use the following code and call the function parseSecond("foo") to get the foo parameter on page1. You can find more information about this on the question page.
function parseSecond(val) {
var result = "Not found",
tmp = [];
var items = location.search.substr(1).split("&");
for (var index = 0; index < items.length; index++) {
tmp = items[index].split("=");
if (tmp[0] === val) result = decodeURIComponent(tmp[1]);
}
return result;
}
If you then want to redirect to page 2 you can write the following code to redirect the frame from page1 to page2 when the foo parameter has the value equal to bar.
if(parseSecond("foo")=="bar"){
window.location="www.example.com/page2";
}

Javascript/jQuery - Check iframe is on another domains

I have a script which handles something in content of the frames. I want to except iframe from another domains (cross-domains) or filter iframe of same domain.
function isCrossDomain(ifr) {
// what i need
// Return true or false
}
if (! isCrossDomain(ifr)) {
var doc = ifr.contents();
}
<iframe name="myFrame" id="myFrame" src="child.html" style="height: 50%; width: 50%;" onload="checkForCross()"></iframe>
function checkForCross()
{
var iframe = document.getElementById("myFrame");
var loc = iframe.contentDocument.location.href;
}
I hope I am understanding you correctly. Just collect the iframes that match your conditional. Lets just say in this case, its yourdomain.com
Once you have your collection of matches, then you can extract the contents() from them.
You can create a regex to capture the match you want.
var iFRMS = jQuery('body').find('iframe').map(function(n, i){
if (jQuery(i).prop('src').match('yourdomain.com')){
return this;
}
});

Is there a client-side way to detect X-Frame-Options?

Is there any good way to detect when a page isn't going to display in a frame because of the X-Frame-Options header? I know I can request the page serverside and look for the header, but I was curious if the browser has any mechanism for catching this error.
OK, this one is old but still relevant.
Fact:
When an iframe loads a url which is blocked by a X-Frame-Options the loading time is very short.
Hack:
So if the onload occurs immediately I know it's probably a X-Frame-Options issue.
Disclaimer:
This is probably one of the 'hackiest' code I've written, so don't expect much:
var timepast=false;
var iframe = document.createElement("iframe");
iframe.style.cssText = "position:fixed; top:0px; left:0px; bottom:0px; right:0px; width:100%; height:100%; border:none; margin:0; padding:0; overflow:hidden; z-index:999999;";
iframe.src = "http://pix.do"; // This will work
//iframe.src = "http://google.com"; // This won't work
iframe.id = "theFrame";
// If more then 500ms past that means a page is loading inside the iFrame
setTimeout(function() {
timepast = true;
},500);
if (iframe.attachEvent){
iframe.attachEvent("onload", function(){
if(timepast) {
console.log("It's PROBABLY OK");
}
else {
console.log("It's PROBABLY NOT OK");
}
});
}
else {
iframe.onload = function(){
if(timepast) {
console.log("It's PROBABLY OK");
}
else {
console.log("It's PROBABLY NOT OK");
}
};
}
document.body.appendChild(iframe);
Disclaimer: this answer I wrote in 2012(Chrome was version ~20 at that time) is outdated and I'll keep it here for historical purposes only. Read and use at your own risk.
Ok, this is a bit old question, but here's what I found out (it's not a complete answer) for Chrome/Chromium.
the way do detect if a frame pointing to a foreign address has loaded is simply to try to access its contentWindow or document.
here's the code I used:
element.innerHTML = '<iframe class="innerPopupIframe" width="100%" height="100%" src="'+href+'"></iframe>';
myframe = $(element).find('iframe');
then, later:
try {
var letstrythis = myframe.contentWindow;
} catch(ex) {
alert('the frame has surely started loading');
}
the fact is, if the X-Frame-Options forbid access, then myFrame.contentWindow will be accessible.
the problem here is what I called "then, later". I haven't figured out yet on what to rely, which event to subsribe to find when is the good time to perform the test.
This is based on #Iftach's answer, but is a slightly less hacky.
It checks to see if iframe.contentWindow.length > 0 which would suggest that the iframe has successfully loaded.
Additionally, it checks to see if the iframe onload event has fired within 5s and alerts that too. This catches failed loading of mixed content (in an albeit hacky manner).
var iframeLoaded = false;
var iframe = document.createElement('iframe');
// ***** SWAP THE `iframe.src` VALUE BELOW FOR DIFFERENT RESULTS ***** //
// iframe.src = "https://davidsimpson.me"; // This will work
iframe.src = "https://google.com"; // This won't work
iframe.id = 'theFrame';
iframe.style.cssText = 'position:fixed; top:40px; left:10px; bottom:10px;'
+ 'right:10px; width:100%; height:100%; border:none; margin:0; padding:0; overflow:hidden; z-index:999999;';
var iframeOnloadEvent = function () {
iframeLoaded = true;
var consoleDiv = document.getElementById('console');
if (iframe.contentWindow.length > 0) {
consoleDiv.innerHTML = '✔ Content window loaded: ' + iframe.src;
consoleDiv.style.cssText = 'color: green;'
} else {
consoleDiv.innerHTML = '✘ Content window failed to load: ' + iframe.src;
consoleDiv.style.cssText = 'color: red;'
}
}
if (iframe.attachEvent){
iframe.attachEvent('onload', iframeOnloadEvent);
} else {
iframe.onload = iframeOnloadEvent;
}
document.body.appendChild(iframe);
// iframe.onload event doesn't trigger in firefox if loading mixed content (http iframe in https parent) and it is blocked.
setTimeout(function () {
if (iframeLoaded === false) {
console.error('%c✘ iframe failed to load within 5s', 'font-size: 2em;');
consoleDiv.innerHTML = '✘ iframe failed to load within 5s: ' + iframe.src;
consoleDiv.style.cssText = 'color: red;'
}
}, 5000);
Live demo here - https://jsfiddle.net/dvdsmpsn/7qusz4q3/ - so you can test it in the relevant browsers.
At time of writing, it works on the current version on Chrome, Safari, Opera, Firefox, Vivaldi & Internet Explorer 11. I've not tested it in other browsers.
The only thing I can think of is to proxy an AJAX request for the url, then look at the headers, and if it doesn't have X-Frame-Options, then show it in the iframe. Far from ideal, but better than nothing.
At least in Chrome, you can notice the failure to load because the iframe.onload event doesn't trigger. You could use that as an indicator that the page might not allow iframing.
Online test tools might be useful.
I used https://www.hurl.it/.
you can clearly see the response header.
Look for X-frame-option. if value is deny - It will not display in iframe.
same origin- only from the same domain,
allow- will allow from specific websites.
If you want to try another tool, you can simply google for 'http request test online'.
This is how I had checked for X-Frames-Options for one of my requirements. On load of a JSP page, you can use AJAX to send an asynchronous request to the specific URL as follows:
var request = new XMLHttpRequest();
request.open('GET', <insert_URL_here>, false);
request.send(null);
After this is done, you can read the response headers received as follows:
var headers = request.getAllResponseHeaders();
You can then iterate over this to find out the value of the X-Frames-Options. Once you have the value, you can use it in an appropriate logic.
This can be achieved through
a) Create a new IFrame through CreateElement
b) Set its display as 'none'
c) Load the URL through the src attribute
d) In order to wait for the iframe to load, use the SetTimeOut method to delay a function call (i had delayed the call by 10 sec)
e) In that function, check for the ContentWindow length.
f) if the length > 0, then the url is loaded else URL is not loaded due to X-Frame-Options
Below is the sample code:
function isLoaded(val) {
var elemId = document.getElementById('ctlx');
if (elemId != null)
document.body.removeChild(elemId);
var obj= document.createElement('iframe');
obj.setAttribute("id", "ctlx");
obj.src = val;
obj.style.display = 'none';
document.body.appendChild(obj);
setTimeout(canLoad, 10000);
}
function canLoad() {
//var elemId = document.getElementById('ctl100');
var elemId = document.getElementById('ctlx');
if (elemId.contentWindow.length > 0) {
elemId.style.display = 'inline';
}
else {
elemId.src = '';
elemId.style.display = 'none';
alert('not supported');
}
}

Categories

Resources