AJAX error running on Yun, but works on PC

Topic: running a web page on the Yun with AJAX GET

I have spent a while trying to figure out why this does not run in the Yun but runs on the PC
(same zepto.min.js, same browser)
Web page is reduced to just where the problem happens…

Code:

Data=

Getting data...

Error traced to zepto.min.js:

k=h.defaultView.getComputedStyle
“Unable to get property ‘getComputedStyle’ of undefined or null reference”
where “h” is [object DispHTMLDocument]


Must be something that is different on how zepto.min.js runs on the Yun linino versus the PC???

Url “http://localjsondevice/tstat” should be same domain and same port number and same protocol as Web page hosting.
Otherwise you need either setup up Cross-Origin Resource Sharing or JSONP.

Hi - thanks for the reply,

The port number should be the same. As to the domain, it is all on a local home network (mostly Windows) with a common HOMEGROUP. All are using the same WiFi. I can ping the device from the Yun and I can also access it via a CURL request on the Yun. In fact right now my (slow) workaround is to do a process CURL request on the Arduino side to get the data.

That is why it is a bit confusing why the AJAX request won' work. Can you please help with how I might best check what you suggest for common domain and port?

Thank you

The problem is with the web browser's same-origin policy. If you're serving a page from the Yun, it can only access APIs and other pages that are also served from the Yun. Similarly if the page is served from a PC, it can only access stuff on that PC. This is a security measure that all web browsers enforce and unfortunately is not easy to get around.

What code is powering http://localJsonDevice/tstat, is it something you have control over? If so look at adding JSONP support, which is one way to get around the same-origin policy. Another option is CORS, but I've never really used it and it seems like kind of a pain compared to JSONP.

I was hoping it would be straightforward. I read what you posted and mostly understand. Lots of hoops to jump through!

To answer the question, the http://localjsondevice/tstat is a WiFi thermostat so I don't have any control over it. When I CURL to it I get back a JSON string that I was hoping to use the AJAX code and parse to get the data.

I guess I will have to stick to the Yun arduino side to do the CURL call and parse with substring(). It works, but I tried the AJAX method to see if I could do that all on the Linux / web page side...

Thanks so much. Unless there are other suggestions I will stick with what I have.

PS: When I run it on the PC side (as a file on the PC with the AJAX request) I do get a security warning that I tell to skip. (IE 11). and the data comes through. No such luck when the page is on the Yun SD card.

Yeah, unfortunately cross site security can be a pain. Putting a simple API on the Yun to run curl sounds like a good approach--that's another common way people get around cross site issues, by proxying calls through their server to the desired service. If it's really painful to parse the thermostat data on the ATmega, you might look at making a PHP or other CGI script that runs on the Linux side and does the proxying. Check out this thread for a little more info on enabling it: http://forum.arduino.cc/index.php?topic=187386.0 You could drop a PHP file in the /mnt/sda1/arduino/www folder and make a simple API that calls the thermostat, parses the data, etc. Because that PHP file would be served from the Yun, a browser would have no issues with your webpage (also served from the Yun) calling the PHP API.

Thank you - I will work on that. I installed PHP5 and it’s CGI with OPKG now trying to get a simple example to work (some security issue?)

I wonder if anyone has done this before on the Yun (examples are so helpful!)

I haven't done much with PHP unfortunately (more of a python guy), but it looks like there are simple proxy scripts you can probably use, like: http://benalman.com/projects/php-simple-proxy/ Try copying that ba-simple-proxy.ph to the Yun's web root (like /mnt/sda1/arduino/www if you want it on the SD card). Then make an AJAX request to http://yun_address/sd/ba-simple-proxy.ph?url=thermostat_api_url in your web page being served from the Yun. The response should be a JSON object with contents, status, and headers fields. Check the comment at the top of the proxy's source file for more info on its parameters and response.

I read your link. I found something that works with PHP_CURL:

<?php
$ch = curl_init("http://thermostat/tstat");
curl_setopt($ch, CURLOPT_HEADER, 0);
 //TRUE to return the transfer as a string
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$results = curl_exec($ch);
var_dump(json_decode($results));
var_dump(json_decode($results, true));
curl_close($ch);
fclose($fp);
echo "

Done!";
?>