0

I'm trying to create a web client to control my Sonos speaker from. The speaker connects to your wifi and acts as a media server for various streaming services.
It operates via SOAP post requests for UPnP actions. I've figured out which SOAP requests do what for it, but I'm having trouble creating a script that works to control it from my web browser.

My school's web server uses Apache, and I've tried adding the following line to the .htaccess file of the directory where my script/webpage is located, to no avail:

Header set Access-Control-Allow-Origin "*"

Is there any way that a user could go to the website (even though it's being hosted by a third party server), put in their target device's IP address, and have the request send from the user's IP to the target device?

If not, could this script be run locally on the browser so that there is no third party server involved? Would that make it work? And if so, how would I go about doing either of these things?

Here's the code I have so far:

<html>
<head>
    <title>SOAP JavaScript Client Test</title>
    <script type="text/javascript">
        function play() {
            var xmlhttp = new XMLHttpRequest();
            xmlhttp.open('POST', 'http://192.168.1.197:1400/', true);

            // build SOAP play request
            var play =

                'POST /MediaRenderer/AVTransport/Control HTTP/1.1' +
                'ORIGIN: '
                'HOST: 192.168.1.197:1400' +
                'SOAPACTION: "urn:schemas-upnp-org:service:AVTransport:1#Play"' +
                'CONTENT-TYPE: text/xml ; charset="utf-8"' +
                'Content-Length: 356' +
                '<?xml version="1.0" encoding="utf-8"?>' +
                '<s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">' +
                   '<s:Body>' +
                      '<u:Play xmlns:u="urn:schemas-upnp-org:service:AVTransport:1">' +
                         '<InstanceID>0</InstanceID>' +
                         '<Speed>1</Speed>' +
                      '</u:Play>' +
                   '</s:Body>' +
                '</s:Envelope>';

            xmlhttp.onreadystatechange = function () {
                if (xmlhttp.readyState == 4) {
                    if (xmlhttp.status == 200) {
                        alert('done. use firebug/console to see network response');
                    }
                }
            }
            // Send the POST request
            xmlhttp.setRequestHeader('Content-Type', 'text/xml');
            xmlhttp.send(play);
            // send request
            // ...
        }
    </script>
</head>

<body>
    <form name="Demo" action="" method="post">
        <div>
            <input type="button" value="Play" onclick="play();" />
        </div>
    </form>
</body>
</html>

I get the following error from the console when I attempt to run it:

XMLHttpRequest cannot load http://192.168.1.197:1400/. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://cs12students.dce.harvard.edu' is therefore not allowed access.

My idea is to have the user enter their 'Device IP:Port', or somehow discover it on their network (not sure if that's possible either, seems like it could be some kind of security breach), assign a variable to it, and then plug it into each script for a different action.

Sachith Muhandiram
  • 2,819
  • 10
  • 45
  • 94

1 Answers1

0

Someone already had your problem on stackoverflow, link to the answer : https://stackoverflow.com/a/24285136/6512354

Community
  • 1
  • 1
Rafik Tighilt
  • 2,071
  • 1
  • 15
  • 27