This is not loading the website that I wanted.
$('#example').load("http://www.example.com");
http://www.jsfiddle.net/JFdVv/
You can't load content from a domain other than the one you're on unless it's JSONP (JSON with a function wrapper)...you can't load plain HTML like you're trying, it's blocked for security reasons by the same origin policy.
As an aside, the reason you get an error with example_ajax_request inline in the page is that by default jsfiddle puts your JavaScript code in a wrapper...you need to have functions like that directly in the page (global functions, not scoped to a ready handler), notice the first drop down up top...it needs to be "no wrap" (either one), instead of "onDomReady".
If you really must load a page from different website, you can always use an <iframe> although this practice would be questionable to say the least.
Or, for a server-side solution, if you're using PHP, you can have a look at the PHP cURL library.
Related
Here's the scenario, not sure what I'm missing.
Page A.htm makes an ajax request for page B.htm, and inserts the response into the page.
Page B.htm contains links to several other JS files, many of which contain a document.ready() function to initialize them.
This works fine when A.htm and B.htm are on the same server but not when they are on different servers.
What I think I'm seeing here, is that when page A and B are on different servers (cross domain ajax), the external resources are being returned asynchronously, or at least out of order, so scripts are executing expecting JQuery.UI to be loaded already, when it is not.
Appreciate any pointers or advice. Apologies for the poor explanation.
You are injecting HTML + script tags via jQuery. In this case *:
HTML content except scripts are injected in the document
Then all scripts are executed one by one
If a script is external then it is downloaded and executed asynchronously
Therefore an external or inline script that depends on jQuery UI might execute before jQuery UI.
One possible solution is to change the way your pages work:
Get rid of external scripts in pageb.html but keep inline scripts
Load the required scripts in pagea.html
Load pageb.html
Another solution is to roll your own jQuery function that will:
Strip all <script src> elements from HTML
Download and execute those scripts in order
Inject the remaining HTML
* The exact behavior is not documented. I had to look into the source code to infer the details.
you are correct in your impression that the issue is a difference in how the requests are handled cross-domain.
Here is a link to get you on the right track : How to make synchronous JSONP crossdomain call
However, you will have to actually re-achitect your solution somewhat to check if the resource has been loaded before moving on. There are many solutions (see the link)
You can set a timer interval and check for something in the dom, or another reasonable solution (despite it's lack of efficiency) is to create a "proxy" serverside (eg php) file on your server and have that file do the cross-domain request, then spit out the result.
Note that since jquery UI is a rather large file, it's conceivable that the cross-domain request finishes first, and executes immediately, even though jqueryUI is not loaded yet. In any case, you're going to have to start thinking about having your app react rather than follow a sequence.
How can I get the html of an iframe without physically putting the iframe on the page? Can I put the iframe into a variable and get it that way?
If you're using node.js (which I would recommend for this), then take a look at jsdom.
As for javascript specifically, you cannot make a call to an external page using javascript (without using hacky methods), as it would violate Cross-domain policy
An untested afterthought, but you might be able to put an iframe hidden through css and then access the content through the document/jquery.
You can make a php-page with the HTML-content,
Easily include the file with php include:
<?php
include "filename.php";
?>
but...why?
You cannot use javascript to get content from cross domain url. So even if you have actual iframe element on your page, you will not be able to access its elements using javascript. This is called Same Origin Policy.
though JSONP is an alternative to your case, you will not be able to access elements inside iframe. You can use Jquery and JSONP to get html of cross domain page
Another option For this scenario is, you can grab the content from server side scripting language like c#, PHP
In this John Resig article, he's is dealing with a dictionary-sized list of words with javascript, and he's loading the content via ajax from a CDN.
The words are loaded in with newlines separating the words. Then he says cross domain fails:
There's a problem, though: We can't load our dictionary from a CDN!
Since the CDN is located on another server (or on another sub-domain,
as is the case here) we're at the mercy of the browser's cross-origin
policy prohibiting those types of requests. All is not lost though -
with a simple tweak to the dictionary file we can load it across
domains.
First, we replace all endlines in the dictionary file with a space.
Second, we wrap the entire line with a JSONP statement. Thus the final
result looks something like this:
dictLoaded('aah aahed aahing aahs aal... zyzzyvas zzz');
This allows us to do an Ajax request for the file and have it work as
would expected it to - while still benefiting from all the caching and
compression provided by the browser.
So, if I'm reading this correctly, simply adding his method dictLoaded('original content') around the original content alone causes the ajax request to not fail.
Is that (turning it into a function + param) really all it takes? and why does JSONP solve the problem of cross domain access restriction?
the <script> tags can load any JS file from anywhere (even cross domain). The nice thing that comes with it is that the code inside that script is also executed, therefore, a method of bypassing cross-domain restrictions.
The problem is, when the code gets executed, it's executed in the global scope. so having this code:
var test = 'foo'
will create a test variable in the global scope.
To mitigate this, you use enclose the reply in a function. This is the "P" in "JSONP" which means "padding". This encloses your reply in a function call.
So if your foreign script has:
myFunction({
test : 'foo'
});
It calls myFunction and passes an object with test key which has value foo. The receiving function would look like:
function myFunction(data){
//"data.test" is "foo"
}
Now we have successfully bypassed the cross-domain restriction. The essential parts needed are:
the receiving function (which can be dynamically created and discarded after use)
the "padded" JSON reply
Is that (turning it into a function + param) really all it takes?
Yes.
and why does that solve the problem of cross domain access restriction?
You should read about JSONP. The idea is that you can now include a <script> tag dynamically pointing to the resource instead of sending an AJAX request (which is prohibited). And since you have wrapped the contents with a function name, this function will be executed and passed as argument the JSON object. So all that's left for you is to define this function.
It is because of the JSONP statement that he added.
"JSON with padding" is a complement to the base JSON data format. It provides a method to request data from a server in a different domain, something prohibited by typical web browsers because of the Same origin policy.
This works via script element injection.
JSONP makes sense only when used with a script element. For each new JSONP request, the browser must add a new element, or reuse an existing one. The former option - adding a new script element - is done via dynamic DOM manipulation, and is known as script element injection. The element is injected into the HTML DOM, with the URL of the desired JSONP endpoint set as the "src" attribute. This dynamic script element injection is usually done by a javascript helper library. jQuery and other frameworks have jsonp helper functions; there are also standalone options.
Source: http://en.wikipedia.org/wiki/JSONP
I have a file: 1.html and an iframe inside it.
I want to access an element (lets say myelement) which exists in 1.html (outside of iframe) from the iframe.
How can I do that?
I tried:
top.getElementById("myelement")
top.document.getElementById("myelement")
parent.getElementById("myelement")
parent.document.getElementById("myelement")
but it didn't work!!
Communication between an iframe and parent document is not possible for cross-origin resources. It will only work if the iframe and the containing page are from the same host, port and protocol - e.g. http://example.com:80/1.html and http://example.com:80/2.html
For cross-origin resources, you can make use of window.postMessage to communicate between the two, but this is only useful if the browser supports this method and if you have control over both resources.
Edit - assuming both resources are from the same origin
In the iframe, window.parent refers to the global object of the parent document, not the document object itself. I believe you would need to use parent.document.getElementById
Assuming that same origin policy is not a problem, you can use parent.document to access the elements, and manipulate them.
Demo here, source of outer frame here, source of iframe here.
parent.document Not working
For cross-origin resources, you can make use of window.postMessage to communicate between the two, but this is only useful if the browser supports this method and if you have control over both resources.
Communication between an iframe and parent document is not possible
for cross-origin resources
that is in so many ways wrong, i dont even WANT to know where to begin. Of course cross-domain requests and algorith-exchanges have a long history, it is both well documented and working now, one might start JSON-request or even simple XMLHttp-Requests via JQuery, for example, you can even load whole .js-files AND inject them into your code - injecting code in remote sources will of course need an appropriate interface; one may achieve such a thing via communication with the responsible persons, just ask them nicely and maybe they'll cooperate if your project makes sense and has its use.
To answer the question : accessing whole documents would raise the need for transferring it beforehand - i would recommend XML for that purpose because the DOM-tree and XML are nearly interchangeable. Load the tree via .get (.ajax for remote hosts), append it to this and access it just like you want ... sounds easy and if you got some experience it IS easy. If you ever read "cross-domain" and "not possible" in the same sentence again you might as well ignore the poster - there are many people out there who dont know what they're talking about ;-)
So I need to pull some JavaScript out of a remote page that has (worthless) HTML combined with (useful) JavaScript. The page, call it, http://remote.com/data.html, looks something like this (crazy I know):
<html>
<body>
<img src="/images/a.gif" />
<div>blah blah blah</div><br/><br/>
var data = { date: "2009-03-15", data: "Some Data Here" };
</body>
</html>
so, I need to load this data variable in my local page and use it.
I'd prefer to do so with completely client-side code. I figured, if I could get the HTML of this page into a local JavaScript variable, I could parse out the JavaScript code, run eval on it and be good to use the data. So I thought load the remote page in an iframe, but I can't seem to find the iframe in the DOM. Why not?:
<script>
alert(window.parent.frames.length);
alert(document.getElementById('my_frame'));
</script>
<iframe name="my_frame" id='my_frame' style='height:1px; width:1px;' frameBorder=0 src='http://remote.com/data.html'></iframe>
The first alert shows 0, the second null, which makes no sense. How can I get around this problem?
Have you tried switching the order - i.e. iframe first, script next? The script runs before the iframe is inserted into the DOM.
Also, this worked for me in a similar situation: give the iframe an onload handler:
<iframe src="http://example.com/blah" onload="do_some_stuff_with_the_iframe()"></iframe>
Last but not least, pay attention to the cross-site scripting issues - the iframe may be loaded, but your JS may not be allowed to access it.
One option is to use XMLHttpRequest to retrieve the page, although it is apparently only currently being implemented for cross-site requests.
I understand that you might want to make a tool that used the client's internet connection to retrieve the html page (for security or legal reasons), so it is a legitimate hope.
If you do end up needing to do it server-side, then perhaps a simple php page that takes a url as a query and returns a json chunk containing the script in a string. That way if you do find you need to filter out certain websites, you need only do this in one place.
The inevitable problem is that some of the users will be hostile, and they then have a license to abuse what is effectively a javascript proxy. As a result, the safest option may be to do all the processing on the server, and not allow certain javascript function calls (eval, http requests, etc).