How to get json data from Server with jquery mobile? - ajax

I am trying to get the Bitcoin course from a web server.
Then we try it with a JSON from local, it works.
In Firebug, I can see the get request to bitcoincharts.com, but there is no answer.
What's wrong with my code?
$('#LitecoinMenue').append('<p><b>Litecoin: 42</b></p>');
$.getJSON('http://api.bitcoincharts.com/v1/weighted_prices.json',
function(data){
$.each(data.USD, function(index,item){
$('#BitcoinMenue').append('<p><b>Bitcoin:'+ item+'</b></p>');
});
});

The reason your code doesn't work is because of a rule called Same-origin policy. This rule requires that all AJAX requests are made to a file on the same domain name. It is not possible to use $.getJSON, or any other AJAX function to load a file from an external domain.
There are only a few options available, the most common is to create a PHP file to act as a proxy, and store it on the same domain. For example:
proxy.php
<?php
$url = base64_decode($_GET['url']);
return file_get_contents($url);
?>
Your page above
$('#LitecoinMenue').append('<p><b>Litecoin: 42</b></p>');
$.getJSON('proxy.php?url=aHR0cDovL2FwaS5iaXRjb2luY2hhcnRzLmNvbS92MS93ZWlnaHRlZF9wcmljZXMuanNvbg==',
function(data){
$.each(data.USD, function(index,item){
$('#BitcoinMenue').append('<p><b>Bitcoin:'+ item+'</b></p>');
});
});
Important Notes:
This is just an example. In a real life situation you would probably want to use cURL to get your file. You should also ensure that it is secured so that someone cannot use Firebug to send an AJAX request to fetch a big file (like a movie) or your server could crash.
As you can see, the URL is base64 encoded. This is to ensure that it gets processed correctly as sometimes there are issues when passing an unencoded URL as a GET parameter. You can encode and decode base64 strings with these online converters: http://base64encode.org and http://base64decode.org, or you can use the built in PHP functions base64_encode() and base64_decode().

Related

Retrieving XML data from a ReST service across domains with Dojo

I am trying to write a browser-based Javascript client for a ReST application which responds with XML (so it seems JSONP is out of the questions).
I am trying to retrieve the data using dojo.io.script.get but the parameter that is passed to the callback function is an object from which it seems I cannot retrieve the XML data of the response.
dojo.io.script.get({url:"http://enterpriseapp.enterprisedomain/path/to/rest/collection",
load:function (data) {
// 'data' does not contain the actual response (which is XML)
}
});
What is the correct way to retrieve this data?
The dojo.io.script.get method will inject a <script> from the specified web address. The data content from this script will be passed to your load function; hence, the content must validate as Javascript. You can't load XML into a script tag.
If you want to load XML, you'll need to use dojo.xhrGet; however, this will not allow requests to 3rd party urls. The advantage of using dojo.io.script.get is that you can use different origin address' than the page loading them.
dojo.xhrGet({
handleAs: "xml",
load: function(dom){
// do something with the DOM XML object
},
error: function(error){
}
});
See: dojo.xhrGet Documentation
If you are trying to load the XML from another website it's a bit of a dead-end. You can use the Access-Control-Allow-Origin header if you have access to the sending server.
Another solution that I have used is to write a proxy script (in PHP or other server language) to mirror the XML on the correct domain. You'll need to be careful if you do this to include good checks so that your server code is not abused by someone for proxying.
See the following Stackoverflow conversation for more about Access-Control-Allow-Origin:
jQuery XML REST Access-Control-Allow-Origin

Cross Domain issue(Working in IE not in other browser)

I am fetching data from a URL using an AJAX call. It is giving a json object to me.
When I run the application, the page is working fine in IE with a conformation that
the page is accessing information that is not under its control.
This poses a security risk. Do you want to continue?
But that is not working in other browsers like Firefox, Chrome, Safari, etc.
i don't know what is the problem. Please explain to me why it is occurring and how to solve the issue?
My Code:
<!DOCTYPE html>
<html>
<head>
<title>Search Engine</title>
<script src="JS/jquery-1.4.2.min.js"></script>
<script>
$(document).ready(function () {
$.support.cors = true;
// create a script tag element
var script = document.createElement("script");
// set the attribute, using the URL to pass data via query parameters
script.setAttribute("src", "http://192.168.13.111:7090/?uname=bhagirathip&wt=json&fl=*,score");
script.setAttribute("type", "text/javascript");
// add the script tag to the document head, forcing an HTTP request
document.getElementsByTagName("head")[0].appendChild(script);
});
function Search() {
function callbackJsonHandler(data) {
alert(data); // This is the JSON data
}
}
</script>
</head>
<body>
<form id="form">
<div style="text-align: center">
<input type="search" id="searchInput" autofocus />
<input type="button" id="btnSearch" onclick="Search()" value="Search" />
</div>
</form>
</body>
</html>
You can't make cross-domain AJAX calls across domains. This is a security feature in web browsers to prevent malicious JavaScript code from scraping rendered data in a web page and then shipping it off to some rogue website on some other domain.
By restricting AJAX requests to same domain, browser vendors ensure that JavaScript imported from other sources cannot send data to any server other than the server the HTML page was served from.
In Internet Explorer, it's prompting you, but any smart user who encounters such a message is likely to say no. Presenting your users with such warning messages is not a good design practice and does not inspire confidence in the legitimacy of your application.
The only way that you can send data across domains is to use a browser hack technique called "script tag remoting", which essentially involves using HTML elements that aren't restricted by the same domain policy. For instance script tags can make HTTP GET requests to any server:
// create a script tag element
var script = document.createElement("script");
// set the attribute, using the URL to pass data via query parameters
script.setAttribute("src","http://192.168.9.11/userInput/?key="+userInput);
script.setAttribute("type","text/javascript");
// add the script tag to the document head, forcing an HTTP request
document.getElementsByTagName("head")[0].appendChild(script);
Using this method, you can send data to a remote server. Note that, to get JSON data back, you must wrap it, or pad it, in a JavaScript function and define a callback in the JavaScript code to handle the response:
function callbackJsonHandler(data) {
alert(data); // This is the JSON data
}
And your server-side code must return content text/javascript, calling the handler, and passing your JSON as an argument:
callbackJsonHandler({"key":"value","key1":"value2"});
When the browser downloads the JavaScript to the browser, the JavaScript runs immediately, giving you a hook to use to access the JSON in the response.
Since you're using jQuery, you can also check out jQuery JSONP, or JSON with Padding, which can be used to generate a JavaScript response so that you can handle callbacks from these requests to the remote server. Note that the server must be setup to handle JSONP requests for this to work properly, similar to the above setup.
Another solution to the issue of making cross-domain requests from a browser whose HTML document is served from exampleA.com to a server whose domain is exampleB.com is to use a proxy.
Let's assume that the HTML document you're working with is served from exampleA.com. You own exampleA.com, and you can access the server side and client side code. exampleB.com, on the other hand, is a remote server owned or controlled by someone else. exampleB.com has some data you want to use in exampleA.com.
We know that AJAX won't work, because of the same origin policy, which is in place to protect rogue apps from doing bad things with people's data. However, servers aren't restricted to same domain policy. This means that your app can do the following:
||exampleA.com/test.html|| ---> http req --> ||exampleA.com/getData|| --http req --> ||exampleB.com/getJSON||
Server-side: (As in your server, exampleA.com):
In other words, on your server that you're using to serve the HTML, you write some code that makes an HTTP request from your server to the third-party server:
// JSON URL which should be requested
$json_url = 'http://www.exampleB.com/getJSON';
// Initializing curl
$ch = curl_init( $json_url );
// Configuring curl options
$options = array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => array('Content-type: application/json')
);
// Setting curl options
curl_setopt_array( $ch, $options );
// Getting results
$result = curl_exec($ch); // Getting JSON result string
See Getting JSON Data with PHP Curl for more details. Each server-side platform has the ability to make HTTP connections to servers.
// now, send the data in the response
HttpResponse::status(200);
HttpResponse::setContentType('application/json');
HttpResponse::setData($result);
HttpResponse::send();
See PHP HTTPResponse. Again, whatever language you're working with should have the ability to return data from a string.
Put the above code in a file called "getJSON.php", assuming you're using PHP. Make sure there is no whitespace between the opening <?php and the beginning of the document; otherwise, you will not be able to set the headers. There is likely a better way to send this response, but since your platform isn't specified, I'll leave that as an exercise for the reader.
Client-side code:
var searchURL = "/getJSON.php"; //From this URL json formatted data is present.
$.ajax({
url: searchURL,
type: 'GET',
dataType: 'json',
contentType: 'application/json; charset=utf-8',
success: function (data) {
try {
alert(data);
}
catch (err) {
alert(err);
}
}
});
Now, in the above JavaScript code, you make a same-domain AJAX request to your server exampleA.com, and then your server makes a request on your behalf to exampleB.com to get the data, then exampleA.com returns the data in the response to the browser.

Screen scraping and proxies using Ruby

I know there are several screen scraping threads on here but none of the answers quite satisfied me.
I am trying to scrape the HTML from an external web page using javascript. I am using $.ajax and everything should work fine. Here is my code:
$.ajax({
url: "my.url/path",
dataType: 'text',
success: function(data) {
var myVar = $.get(url);
alert(myVar);
}
});
The only problem is that it is looking for the specified url within my web server. How do I use a proxy to get to an external web page?
Due to Cross Site Scripting restrictions, you're going to have to pass the desired URL to a page on your server that will query the URL in question from serverside, and then return the results to you. Take a look at the thread below and the incorporate that into your application and have it return the source when that page is hit by your AJAX function.
How to get the HTML source of a webpage in Ruby
Using a GET request is going to the be easiest way to transfer the URL of the page you want to fetch your server so you'll be able to call something like:
$.ajax("fetchPage.rb" + encodeURI(http://www.google.com))
Because you can't access the side in question directly from the server, you're going to have to pipe the serverside script through a proxy for the request to work, which really kind of depends on your setup. Taking a look at the Proxy class in Ruby:
http://ruby-doc.org/stdlib-1.9.3/libdoc/net/http/rdoc/Net/HTTP.html#method-c-Proxy

Cross domain javascript ajax request - status 200 OK but no response

Here is my situation:
Im creating a widget that site admins can embed in their site and the data are stored in my server. So the script basically has to make an ajax request to a php file in my server to update the database. Right? Right :)
The ajax request works excellent when i run it in my local server but it does not work when the php file is on my ONLINE server.
This is the code im using:
var url = "http://www.mydomain.net/ajax_php.php";
var params = "com=ins&id=1&mail=mymail#site.net";
http.async = true;
http.open("POST", url, true);
http.onreadystatechange = function() {
if(http.readyState == 4 && http.status == 200) {
//do my things here
alert( http.responseText );
}
}
http.send(params);
In firebug it shows: http://www.mydomain.net/ajax_php.php 200 OK X 600ms.
When i check the ajax responnseText I always get a Status:0
Now my question is: "Can i do cross-domain ajax requests by default? Might this be a cross-domain ajax problem? Since it works when the requested file resides in my local server but DOESN'T work when the requested file is in another server, im thinking ajax requests to another remote server might be denied? Can you help me clear on this?
Thanks..
Cross-domain requests are not directly allowed. However, there is a commonly-used technique called JSONP that will allow you to avoid this restriction through the use of script tags. Basically, you create a callback function with a known name:
function receiveData(data) {
// ...
}
And then your server wraps JSON data in a function call, like this:
receiveData({"the": "data"});
And you "call" the cross-domain server by adding a script tag to your page. jQuery elegantly wraps all of this up in its ajax function.
Another technique that I've had to use at times is cross-document communication through iframes. You can have one window talk to another, even cross-domain, in a restricted manner through postMessage. Note that only recent browsers have this functionality, so that option is not viable in all cases without resorting to hackery.
You're going to need to have your response sent back to your client via a JSONP call.
What you'll need to do is to have your request for data wrapped in a script tag. Your server will respond with your data wrapped in a function call. By downloading the script as an external resource, your browser will execute the script (just like adding a reference to an external JS file like jQuery) and pass the data to a known JS method. Your JS method will then take the data and do whatever you need to do with it.
Lots of steps involved. Using a library like jQuery provides a lot of support for this.
Hope this helps.

Can I use XMLHttpRequest on a different port from a script file loaded from that port?

I have website that use XMLHttpRequest (jQuery, actually). I also have another site running on the same server, which serves a script file that makes XHR requests back to THAT site, ie.
http://mysite:50000/index.html includes
<script src="http://mysite:9000/otherscript.js"></script>
and http://mysite:9000/otherscript.js includes
$.ajax({
url: 'http://mysite:9000/ajax/stuff'
});
The problem is - this doesn't work. The AJAX requests from the loaded script simply fail with no error message. From what I've been able to find this is the old same origin policy. Given that I control both sites, is there anything I can do to make this work? The "document.domain" trick doesn't seem to do a thing for XMLHttpRequest.
Nope- can't do this with XHR. Same-domain policy is very restrictive there- same host, same port, same protocol. Sorry! You'll have to resort to other tricks (iframes, title manipulation, etc) to get it to work.
You can do this by adding Access-Control-Allow-Origin header.
If you are using PHP
header("Access-Control-Allow-Origin: http://example.com");
or in Node.js
response.writeHead(200, {'Access-Control-Allow-Origin':' http://example.com'});
This should do the trick for you. It always works for me.
I just solved a similar issue with a PHP service I'm currently playing around with (not sure how relevant a PHP solution is to this directly, but...) by making a single line proxy PHP page, SimpleProxy.php:
<?php
echo file_get_contents('http://localhost:4567');
?>
And in my XMLHttpRequest I use 'SimpleProxy.php' in place of 'http://localhost:4567', which effectively puts the request on the same domain as my .js code.

Resources