How to make a page full accesible by iFrame - php

The page 1 works an loads well into an iframe, but when I try to access through JS I got this error.
Uncaught DOMException: Blocked a frame with origin "https://domain1.com" from accessing a cross-origin frame (the frame that is trying to access is in "https://domain2.com" )
I'have the full access in both servers, and I already tried with 'X-Frame-Options' & header 'Access-Control-Allow-Origin' header, even tried to remove the X-Frame-Options header.
I don't know what else do.

I recommend that you not use iframes for your use case. Instead, fetch the content that you want to insert into the page through an XHR call, and insert it directly into the page. This only works if you're inserting your own content that you control.
That way, the content will actually be in the DOM of your main web page, and the outer elements around your content will grow in height automatically, subject to your CSS overflow setup and that kind of thing.
Here's an example of how I load a central footer from a corporate web site onto lots of web sites from the same company:
...
<div id='lazyFooter'></div>
</body>
<script>
function footerCallback(json_data){
document.getElementById('lazyFooter').outerHTML = json_data[0];
}
window.onload = function() {
var script = document.createElement('script');
script.src = 'https://footers.ourcompany.com/footer.min.json'
script.async = true;
document.getElementsByTagName('head')[0].appendChild(script);
}
</script>
This example uses JSONP, so the file that you load needs to be formatted as a Javascript function:
footerCallback(["\ <style class=\"embed\">\n\
#font-face{font-family:'Darby Sans ... </style><footer class=\"
... </div>\n\ </footer>\n\ "]);
If you're embedding someone else's content and it's not formatted as a JSONP response, then you have (at least) two options:
Use an iframe instead and deal with the Javascript hassles to set the height. (Ugly, not portable across browsers.)
Deploy a simple server-side microservice with an AWS Lambda function or something, for fetching the third-party content on the server side and packaging it as a JSONP response that you can embed in your page. Or, if you can run that microservice on the same domain as your site, then you don't need to worry about JSONP and you can simply proxy bare HTML from the third-party site through the microservice to your XHR call.

Related

How to get html source code after javascript transformation?

for a project at school I am trying to make a website that can show your grades in a prettier way than it's being done now.
I have been able to log in to the site using cURL and now I want to get the grades in a string so I can edit it with PHP.
The only problem is that cURL gets the html source code when it hasn't been edited by the javascript that gets the grades.
So basically I want the code that you get when you open firebug or inspector in a string so I can edit it with php.
Does anyone have an idea on how to do this? I have seen several posts that say that you have to wait till the page has loaded, but I have no clue on how to make my site wait for another third-party site to be loaded.
The code that I am waiting to be executed and of which I want the result is this:
<script type="text/javascript">
var widgetWrapper = $("#objectWrapper325");
if (widgetWrapper[0].timer !== undefined) {
clearTimeout( jQuery('#objectWrapper325')[0].timer );
}
widgetWrapper[0].timer = setTimeout( function() {
if (widgetWrapper[0].xhr !== undefined) {
widgetWrapper[0].xhr.abort();
}
widgetWrapper[0].xhr = jQuery.ajax({
type: 'GET',
url: "",
data: {
"wis_ajax": 1,
"ajax_object": 325,
'llnr': '105629'
},
success: function(d) {
var goodWidth = widgetWrapper.width();
widgetWrapper.html(d);
/* update width, needed for bug with standard template */
$("#objectWrapper325 .result__overview").css('width',goodWidth-$("#objectWrapper325 .result__subjectlabels").width());
}
});
}, 500+(Math.random()*1000));
</script>
First you have to understand a subtle but very important difference between using cURL to get a webpage, and using your browser visiting that same page.
1. Loading a page with a browser
When you enter the address on the location bar, the browser converts the url into an ip address . Then it tries to reach the web server with that address asking for a web page. From now on the browser will only speak HTTP with the web server. HTTP is a protocol made for carrying documents over network. The browser is actually asking for an html document (A bunch of text) from the web server. The web server answers by sending the web page to the browser. If the web page is a static page, the web server is just picking an html file and sending it over network. If it's a dynamic page, the web server use some high level code (like php) to generate to the web page then send it over.
Once the web page has been downloaded, the browser will then parse the page and interprets the html inside which produces the actual web page on the browser. During the parsing process, when the browser finds script tags it will interpret their content as javascript, which is a language used in browser to manipulate the look of the web page and do stuff inside the browser.
Remember, the web server only sent a web page containing html content he has no clue of what's javascript.
So when you load a web page on a browser the javascript is ONLY interpreted once it is downloaded on the browser.
2. What is cURL
If you take a look at curl man page, you'll learn that curl is a tool to transfer data from/to servers which can speak some supported protocols and HTTP is one of them.
When you download a page with curl, it will try to download the page the same way your browser does it but will not parse or interpret anything. cURL does not understand javascript or html, all it knows about is how to speak to web servers.
3. Solution
So what you need in your case is to download the page like cURL does it and also somehow make the javascript to be interpreted as if it was inside a browser.
If you had follwed me up to here then you're ready to take a look at CasperJS.

Loading pages with dynamic content

I've been working on a project for a couple of Minecraft servers that use Bukkit. I'm trying to create a web page that contains a dynamic map of the servers' worlds, as well as a real-time event update system, where a <div> is updated as events happen on the server. To give a brief outline of how my system works, the Minecraft servers communicate events with a Node.js webserver over the same network via UDP packets, and the Node.js webserver uses these packets to build JavaScript objects containing the event info. The objects are then stored, and passed to Jade whenever the page is requested. Jade takes care of the templating.
What I want to do is update this page dynamically, so that the user doesn't have to refresh the entire page to update the list of events. What I'm trying to implement is something like the Facebook ticker, which updates every time a Facebook friend does something like posting a status, commenting on a post, or 'liking' a post.
In reading this question on SO, I've concluded that I need to use long polling in a PHP script, but I'm not sure of how to integrate PHP with a webserver written almost entirely in Node.js. How could I go about doing this?
EDIT:
I've run into a problem in the clientside code.
This is the script block:
script(src='/scripts/jadeTemplate.js')
script(src='/socket.io/socket.io.js')
script(type='text/javascript')
var socket = io.connect();
socket.on('obj', function(obj) {
var newsItem = document.createElement("item");
jade.render(newsItem, 'objTemplate', { object: obj });
$('#newsfeed').prepend(newsItem);
console.log(obj);
alert(obj);
});
And this is objTemplate.jade:
p #{object}
// That's it.
When the alert() and console.log() are placed at the top of the script, it alerts and logs, but at the bottom, they don't execute (hence, I think it's a problem with either the creation of newsItem, the jade.render(), or the prepend.
If I need to provide any more snippets or files let me know. I'm still tinkering, so I might solve it on my own, but unless I update, I still need help. :)
I'd skip PHP and take a look at socket.io. It uses websockets when possible, but it will fall back to long-polling when necessary, and the client side library is very easy to use.
Whenever your node.js server has a new object ready to go, it will push it to all connected browsers. Use ClientJade to render the object using your template (you may have to break out the relevant part of the main template into its own file), then prepend the generated dom element to your feed.
First, if it isn't this way already, you'll need to break out the relevant part of your jade template into its own file. Call it objTemplate.jade. Then use ClientJade to create a compiled template that can be run in the browser: clientjade objTemplate.jade > jadeTemplate.js. Put jadeTemplate.js in your public js directory.
In your node.js app, you'll have something like this (pseudo-codey):
var io = require('socket.io').listen(httpServer);
listenForUDPPackets(function(obj) {
saveObjSomewhere(obj);
io.sockets.emit('obj', obj);
});
Then on the client, something like this:
<script src="/js/jadeTemplate.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect();
socket.on('obj', function(obj) {
var newsItem = document.createElement();
jade.render(newsItem, 'objTemplate', obj);
$('#newsFeed').prepend(newsItem);
});
</script>

Visit a URL in PHP or javascript in background

I write my scripts in PHP, and there are HTML and javascripts inside. What I want is when I click a button(in HTML), it calls a javascript function, the function should visit a url like "http://localhost/1/2" And the page stays as before. Is it feasible?
I just want it work, no matter in js or php. Thanks.
Since the page is on the same domain, you may use an Ajax request:
var request = new XMLHttpRequest();
request.open("GET", url, true);
request.send(null);
Note that this does not do any error-checking, however. If you need that, there are a multitude of available tutorials easily found with a search.
And since you ask, for pages not on the same domain, using an <iframe> is sometimes possible:
var frame = document.createElement("iframe");
frame.src = url;
frame.style.position = "relative";
frame.style.left = "-9999px";
document.body.appendChild(frame);
This is commonly known as AJAX (being able to send a request to the server and receive a response back without navigating away from the page).
AJAX is supported in ALL modern browsers, but sometimes there are inconsistencies, so it is best to use a javascript framework such as JQuery, YUI or another framework.
I tend to use YUI, so here's a quick example on how to send an AJAX request using YUI. This uses the IO Utility:
// Create a YUI instance using io module.
YUI().use("io", function(Y) {
var uri = "http://localhost/1/2";
// Define a function to handle the response data.
function complete() {
Y.log('success!');
};
// Subscribe to event "io:complete"
Y.on('io:complete', complete);
// Make an HTTP request to 'get.php'.
// NOTE: This transaction does not use a configuration object.
var request = Y.io(uri);
});

How can I load an iFrame with only textual content?

I found the snippet below for creating an iframe:
I'd like to only load the textual content at http://www.host.com and make the iframe invisible using display:none
Background:
I need an effective way to parse out the favicon location. Not all site have a default location. For example <link rel="SHORTCUT ICON" href="../images/logo_small.ico" />.
Hence all I need are the textual contents. PHP has a function that does this ( file_get_contents) but I want to do it on the client side.
Here is the mdn documentation on iframe
For server-side PHP use file_get_contents.
function makeFrame() {
ifrm = document.createElement("IFRAME");
ifrm.setAttribute("src", "http://www.host.com");
ifrm.style.width = 640+"px";
ifrm.style.height = 480+"px";
document.body.appendChild(ifrm);
}
Example of Delicious Bookmarklet:
javascript:(function()
{
f='http://www.delicious.com/save?url='+encodeURIComponent(window.location.href)+
'&title='+encodeURIComponent(document.title)+'&notes='+
encodeURIComponent(''+
(window.getSelection?window.getSelection():document.getSelection?
document.getSelection():document.selection.createRange().text))+'&v=6&';
a=function()
{
if(!window.open(f+'noui=1&jump=doclose','deliciousuiv6','location=1,links=0,scrollbars=0,to
olbar=0,width=710,height=660'))
{
location.href=f+'jump=yes'
}
};
if(/Firefox/.test(navigator.userAgent))
{
setTimeout(a,0);
}
else
{
a();
}
})()
You will only have access to the link element in the iframe when both yours and the framed page are in the same domain. To cite the docs you found:
Scripts trying to access a frame's content are subject to the same-origin policy, and cannot access most of the properties in the other window object if it was loaded from a different domain.
Therefore, it will be needed to use a PHP solution. Load a given domain, use a tagsoup parser and query the dom for link[rel="SHORTCUT ICON"].
You can create a JSON API with that solution, which can be used over Ajax from the clientside js code of your application.
I think you will struggle to get the information client side if the page is located on a different server, due to cross-site scripting restrictions within the browser.
If it is all local you want to look at:
XMLHttpRequest();
and
getResponseText();
I think you are probably best using the PHP method though.
Edit:
This is a similar question I think:
XMLHttpRequest to get HTTP response from remote host
Responses there may be of further assistance.

Cross Domain Ajax Request with JQuery/PHP

Help, if you can-
The situation:
http://foobar.com includes a remotely hosted javacript file (http://boobar.com/stuff.js).
The goal is to just get an alert from the remotely hosted php script on foobar.com
I have tried the following code in stuff.js:
$.ajax({
type: "GET",
url: "http://www.boobar.com/script.php?callback=?",
dataType: 'jsonp',
success: function(result) { alert(result); }
});
No luck.
$.getJSON("http://www.boobar.com/script.php?jsonp=?",
function(data) { alert(data); }
);
Also no luck.
On the php side I have tried both the following:
return json_encode(array(0 => 'test'));
echo json_encode(array(0 => 'test'));
In Firefox I get a security error. I understand that it thinks I'm violating the security model. However, according to the jquery documentation, I should be able to accomplish this.
The error seems to be a security feature of the Same Origin Policy: to simplify, you can only make AJAX requests for stuff on the originating server (http://foobar.com). One way around this is to make a simple facade on the originating server, e.g.:
<?php
// this file resides at http://foobar.com/getstuff.php
echo file_get_contents('http://www.boobar.com/script.php?callback=?'
. $possibly_some_other_GET_parameters );
?>
Then, from foobar.com, you can make an AJAX request for http://foobar.com/getstuff.php (which in turn makes a HTTP GET request from your web server to boobar.com and sends it back to the browser).
To the browser, the request goes to the origin server, and is allowed (the browser has no way of knowing that the response comes from somewhere else behind the scene).
Caveats:
the PHP config at foobar.com must have allow_url_fopen set to "1". Although this is the default setting, some servers have it disabled.
the request to www.boobar.com is made from foobar.com server, not from the browser. That means no cookies or user authentication data are sent to www.boobar.com, just whatever you put into the request URL ("$possibly_some_other_GET_parameters").
You can get data from another server asynchronously using script tags and json:
<script type="text/javascript" src="http://somesite.com/path/to/page/"></script>
You can use this to dynamically load a remote javascript (by created a new script element and setting the src attribute, then loading into the DOM), which could set a variable. However, you need to really trust the remote site, because the JS will be evaluated without any precondition.
There is a method called window.name transport or window.name method which uses a general browser bug(not sure if this is a bug actually). You make the request through an iFrame and the loaded page puts the information you need to the "name" property of the JavaScript window object of itself.
This method uses a "blank.htm" since it first navigates to the target page and then goes back to the blank.htm page to overcome the "same origin policy" restriction.
Dojo have implemented this and you can find a more detailed explanation here.
Also I have implemented a cross-domain XMLHttpRequest object based on this method in the library I have written which can be found here.
You may not be able to use the library since it will need 1 or 2 additional libraries which can be found here.
If you need further help in implementing it in your style, I'll try to do my best.
So what I ended up doing, since it was just a GET - no data need to be retrieved - I used JQuery to create a hidden iframe with the URL including the variables I wanted to pass set as the source. Worked like a charm. To all who provded feedback - Thanks!
How about this !! Using a php proxy.
Cross-Domain AJAX calls using PHP
http://www.phpfour.com/blog/2008/03/cross-domain-ajax-using-php/
jQuery .ajax also has a setting 'crossDomain'.
http://api.jquery.com/jQuery.ajax/
crossDomain (default: false for same-domain requests, true for cross-domain requests)
Type: Boolean
If you wish to force a crossDomain request (such as JSONP) on the same domain, set the value of crossDomain to true. This allows, for example, server-side redirection to another domain. (version added: 1.5)

Categories