JavaScript, JSONP and reading XML from cross-domain - javascript

in my JS project I need to load data from cross-domain. (JavaScript sits on domain A, the data comes from domain B)
I have a solution that uses JSONP but I really need to load an XML instead (ordinary XML music playlist). The main goal is to be able to load and parse the XML data without the need to modify them first to some other format (like JSONP).
Is it completely impossible? Or are there any workarounds or hacks?
I am targeting mainly the latest browsers mainly on iOS.
Thanks!
PS: Could easyXDM be of any help? Or it's not relevant to XMLs?
UPDATE: unfortunately I can not use proxy, I am really asking about a direct solution.

You can totally do this, just have your domain B return something like
func("<myxml></myxml>");
or
var someVar = "<myxml></myxml>";
The name JSONP doesn't really have anything to do with JSON specifically since its concept is all about executing JavaScript that has your data embedded in the code.
Once your domain B returns exactly one of those 2 forms above, domain A can simply use it either by doing:
<script>
function func(xmlString) {
alert(xmlString); // you can parse the xmlString with
// jQuery or something else
}
</script>
or if you use the second example:
<script>
alert(someVar);
</script>

The usual solution is to have a "AJAX proxy" - a simple server-side script running on your domain, that fetches the data from the other domain and returns it unchanged.
The simplist is to give the script the URL you need the data from:
http://example.com/proxy.php?url=http%3A%2F%2Fexample.org%2Fajax%3Fid%3D123 gets the data from http://example.org/ajax?id=123
This can however be misused if you let any URL be fetched like that, so you should have your script, check that it actually only gets data from a specific URL.
In order to avoid having to parse the URL to check this, you could write a proxy specificly for your app, that only accesses the specific resource you need:
http://example.com/proxy.php?id=123 to access http://example.org/ajax?id=123.

If you have a JSON-P solution in place, you can just pass the XML to the JSON-P callback as a string. You can then do XML parsing of a variable string in JavaScript

The whole idea with JSONP is that the response must be executable as script. So sure, you can pass XML data back, as long as it's valid Javascript - for example, the server could wrap its response in a string:
myCallback('<xml><stuff/></xml>')
and you'd have to parse it with jQuery:
success: function(data) {
var xml = $(data); // now do stuff
}
This assumes that you control the other server and/or someone who does is interested in formatting their data that way. Otherwise, you're out of luck, and need a proxy of some sort - you might be able to do this with YQL.

Related

text/html output when requesting JSONP

I have been playing around with the jQuery library the last week or two.
Very handy! I am now playing with the AJAX requests to retrieve things such as the weather, current downloads and more, which have been going well so far!
I have now tried to connect up to my ISP to get my current data usage (peak, off peak etc).
When I use Chrome, I can manually type the variables into the URL and have the required JSON code show in the browser. The issue is, that it seems to return text/html instead of application/json.
When you go into developer tools, it shows text/html. This make it difficult for me to retrieve the data from my home server using AJAX and JSONP. See here for a failed query (but you can still see the text/html output, which is in a JSON format! Failed JSON Query on ISP
My question is, how could I get this data from the server URL, then make it into JSON that jQuery can read?
When I try the .load , $.get functions I run into Cross Origin Issues...
EDIT:Here is the PDF documentation for the API (Download at the bottom of the page)
Notice that I need to append certain values (user / pass / token). My ultimate aim is to have my JS read these values and store them.
The issue is, that it seems to return text/html instead of application/json.
That's a serverside issue. Go and file a bug report.
This make it difficult for me to retrieve the data
Not by itself. You should be able to override the settings how responses are parsed, e.g. in jQuery by using the datatype parameter.
using AJAX and JSONP
Notice that you cannot use JSONP, as it is not supported by that API (judging from the docs and a simple ?callback=test try). If you want support for that, file a bug report against the service provider.
When I try the .load, $.get functions I run into Cross Origin Issues...
Yes. They don't send CORS headers either. I suspect that this API is only used internally, and by devices that are not subject to a same-origin policy.
how could I get this data from the server URL, then make it into JSON that jQuery can read?
Use a proxy on your own server (that runs in the same domain as your app). It can also fix that content-type header.
For more details see also Ways to circumvent the same-origin policy, though most of the methods require cooperation of the service provider (to implement serverside features).
If i understand you correctly You ask for a certain value and it gives you a string. For most API's in the world they send a string that you have to parse into JSON or some language code. I would suggest looking at Parsing JSON Strings link. It explains how to take well formated strings and parse them into JSON readable objects.
var obj = jQuery.parseJSON( '{ "name": "John" }' );
alert( obj.name === "John" );
if you go on further and start using php take a look that Parsing JSON Strings with PHP
EDIT:
use .done() method to grab text from other pages after AJAX call.
$.ajax(...).done(function(html){
//do what you want with the html from the other page
var object = $.parseJSON(html)
}

How to get data from remote website?

Lets say there is a url out there e.g. www.website.com/data.jsp
the link has the following JSON data
{"successful":"true","rows":[{"zip":"65472","user_id":"10843","name":"Rufio"}]}
I just want to be able to extract this data at runtime however I am having a hard time getting it using getJSON
$.getJSON("test2.jsp",function(result){
$("div").append(result.rows[0].user_id + " ");
});
Now if I run it using a local file with the data residing in test2.jsp as shown above it appends the user_id. However when I try to access "www.website.com/data.jsp" instead nothing happens. I don't believe the website is configured to work with JSONP either.
I need a way to figure out how to pull this data from the website at run time. Does anyone have any solutions or workarounds?
p.s. Is this something that might need to be sorted out on the other end? The people who own the website set this scenario up to be like a fake api call like typically you would pass in parameters to get back the specific information that you would need. In the case of this endpoint or url it just returns a single record or the file just contains the data listed above. They would like me to extract the data from their url at runtime.
You can't make a normal ajax call to to this other domain due to same origin policy.
You can use JSONP to load the remote page, but looking at that example output you wouldn't be able to access the data unless the remote site is setup for JSONP (assigning the JSON to a variable, calling a callback function, etc).
You could create a server-side passthrough script of your own. You don't mention what server-side technology you have available, but if you can use PHP, you do a passthrough like this:
<?php
echo file_get_contents("http://www.website.com/data.jsp");
?>
PHP (or any other server-side language) can fetch the remote data, and now you can use ajax to call your own script (which works since you're on the same domain).

Requesting remote XML data with javascript

Ok here's my problem. I'm working on this little site called 10winstreak and I'm trying to detect if a stream is live or not with javascript because our server that we run the site off of cant handle processing every single request with PHP. The basis of detecting if a stream is live or not is you go to their XML file and in one of their tags (if it's live) it will say something along the lines of true and often time the XML file on their site will be empty if a particular stream isn't live. for example if you have a twitch.tv stream for gamespot you go to http://api.justin.tv/api/stream/list.xml?channel=gamespot and if it's got stuff in it then it's live if not then it's not.
so basically my code looks like this:
function check (URL, term){
$.get(URL , function(data){
console.log(data);
//data is whatever the server returns from the request, do whatever is needed with it to show who is live.
var number = data.search(term);
if (number > -1)
{
document.write("Live");
}
else
{
document.write("Offline");
}
});
}
and URL is a url that gets passed in and term is the term to search for in the xml file (usually "true" or "True"). but before anything happens I end up with "XMLHttpRequest cannot load http://api.own3d.tv/liveCheck.php?live_id=6815. Origin (my server's URL) is not allowed by Access-Control-Allow-Origin."
I've looked into it all over the net and i dont seem to be able to find anything that I can use. there's alot of theory stuff but not enough actual code and i dont understand the theory stuff to be able to start typing code out. from what i've seen you have 2 ways to go, use JSONP or add a line somewhere in your sever to allow for cross-domain accessing. neither of which i understand fully nor know how or what to do. It would be alot of help for someone to show me what needs to be done to get rid of this error. of course if you can explain it to a non-coder like me it would be even more awesome but at my current point, as long as the code works for all I care it might as well be magic lol.
You can solve it :)
Take a look at xReader
<script src="http://kincrew.github.com/xReader/xReader.full.js"></script>
<script type="text/javascript">
xReader("http://api.own3d.tv/liveCheck.php?live_id=6815", function(data) {
alert(data.content);
})
</script>
I think you need cacheburst option. but you can be banned from YQL.
I think its because the path is not relative. You may be calling this from a different domain/sub-domain. You can potentially allow other origins to access, which may open up a security hole or you can create a proxy locally.
In PHP creating a proxy is easy: http://blog.proxybonanza.com/programming/php-curl-with-proxy/
Now, instead of directing your request straight to that URL send the request from jQuery to your own local url and have it access it on the server side.
Another option would be to use YQL: http://www.parrisstudios.com/?p=333 (I wrote an article about this a while ago)... In that way you can turn the response into JSON, which can be accessed cross-domain (as can javascript).
You could ask for the API responses to all be returned using a JSONP server and in JSON.
You aren't going to be able to do this via client-side javascript unless they've enabled some way to retrieve their data cross-domain (CORS, JSONP, some flash widgety thing getting read permissions from crossdomain.xml file(s) located on their server...)
Short answer: unless 10winstreak offers a JSONP service, you'll have to do things on the server-side.
Slightly longer answer:
For security reasons browsers won't let you make AJAX requests from www.example.com to www.example2.com (or any other domain except www.example.com). There isn't much you can do about this except use JSONP (and you can only do that if the remote webservice offers it).
Therefore, what you end up needing to do is ask your server "hey what's on that other server?" and (since it's not limited the way a browser is) it can go get the XML from that other server. There are various ways of doing this, either with code or Apache config; not sure what's right for you, but hopefully now you understand the general principle.
P.S. See this question: Wouldn't have been simpler to just discard cookies for cross-domain XHR? if you are curious why browsers do this.
* EDIT *
I just checked out JustinTV's site, and it appears that they already have a PHP library for you to use:
https://github.com/jtvapi/jtv_php_api
This is very likely your best bet (if you want to keep using PHP that is; if not they have libraries for other languages: http://www.justin.tv/p/api).

How does the diigolet bookmarklet get around cross-scripting?

http://www.diigo.com/tools/diigolet
Diigolet essentially allows you to use a bookmarklet to bookmark sites. With the bookmarklet I'm making, I also need to pass the current URL of the site the user is on to my server. Everytime I try this, I get a cross-scripting error.
Does anybody know how to bypass this like the diigolet?
Essentially, they work around the same-origin policy by injecting a script tag with the different-domain URL rather than using an XMLHttpRequest. Note that this is different from a normal JSON request in that the JSON is wrapped in a callback function, for example:
myCallbackFunction(<JSON here>);
(This works because JSON is a subset of JavaScript's object literal notation.)
In their case, they hardcode the name of the callback function as diigolet.callback, but there exists a specification called JSONP that JavaScript libraries such as jQuery support.
Under the JSONP specification, the name of the callback function is passed to the server via a callback=myCallbackFunction parameter in the GET request. Your server-side code needs to handle this appropriately to be able to handle JSONP requests from jQuery.

YUI "Get" utility to parse JSON response?

The documentation page for the YUI "Get" utility says:
Get Utility is ideal for loading your
own scripts or CSS progressively
(lazy-loading) or for retrieving
cross-domain JSON data from sources in
which you have total trust.
...but doesn't have any actual examples for how to do so. Their one example doesn't actually request a JSON document from a remote server, but instead a document containing actual JavaScript along with the JSON data.
I'm just interested in the JSON response from the Google Maps API HTTP (REST) interface. Because I can't do cross-site scripting with the "Connect" utility, I am trying the "Get" utility. But merely inserting some JSON data into the page isn't going to do anything, of course. I have to assign it to a variable. But how?
Also, just inserting JSON data into the page makes Firefox complain that there's a JavaScript error. And understandably! Plain ol' JSON data isn't going to parse as valid JavaScript.
Any ideas?
Normally in this case the easiest thing to do is to return javascript that calls a callback with the json. For example:
function xdCallback( json ) {
// here I can do whatever I need with json, maybe
SomeModule.heresTheJson( json );
// or
globalVar.json = json;
// etc
}
And so on your server side you return not just JSON but instead something like:
xdCallback( { json: 'goes', here: true } );
...execute the 'script' when you get it via your ajax call and you're set.
OK. Looks like without Google's HTTP Geocoding interface supporting JSONP, there is no way to do this. :(
Sean -- You may find that YUI Connection Manager's XDR support is what you're looking for --
http://developer.yahoo.com/yui/examples/connection/xdr.html (YUI 2)
http://developer.yahoo.com/yui/3/examples/io/io-xdr.html (YUI 3)
Use Connection Manager (YUI 2) or IO (YUI 3) to bring in the JSON, and then use the JSON component in either codeline to parse the JSON once it's loaded.
If Google or Yahoo! has the necessary cross-domain support on the relevant servers, you should be in business.
-Eric
I have used YAHOO.lang.JSON.parse to parse a string to json. Also the stringify method can be used to go from JSON back to a string:
http://developer.yahoo.com/yui/docs/YAHOO.lang.JSON.html

Categories

Resources