-2

I have to send a POST request with some data to a RESTful API. Right now I have a C program that creates a socket, connects with the host and successfully sends the POST request.

After some C magic, the request is formed as follows:

POST http://remotemanager.digi.com/ws/sci HTTP/1.1
Host: remotemanager.digi.com
Content-Type: text/xml
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
Content-Length: 123

<sci_request version="1.0"><ping><targets><device id="00000000-00000000-001234FF-FF56789A"/></targets></ping></sci_request>

Then I send it with send from socket.h. Everything works perfectly fine. After sending it, I receive:

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=485A5984C8BB21B11BFB305145FAF3B9; Path=/ws/;         HttpOnly;Secure
Cache-Control: no-store
Pragma: no-cache
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Content-Type: application/xml;charset=ISO-8859-1
Content-Length: 195
Date: Thu, 09 Jan 2020 21:12:17 GMT

<sci_reply version="1.0"><send_message><device id="00000000-00000000-001234FF-FF56789A"><rci_reply version="1.1"><do_command target="RPC_request"/></rci_reply></device></send_message></sci_reply>

The problem is when I try to do this with HTML and Javascript. This is what I'm doing:

<!DOCTYPE html>
<html lang="en-us">
    <head>
        <meta charset="utf-8">
        <title>Ping Gateway</title>
        <script>
            function send_request() {
                var xml =
                '<sci_request version="1.0">\n' +
                    '<send_message>\n' +
                        '<targets>\n' +
                            '<device id="00000000-00000000-001234FF-FF56789A"/>\n' +
                        '</targets>\n' +
                        '</ping>\n' +
                '</sci_request>\n';

                var request = new XMLHttpRequest();

                request.onreadystatechange = function() {
                    if (this.readyState == XMLHttpRequest.DONE && this.status == 200) {

                    }
                    else if (this.status == 401) {
                        document.getElementById("response").innerHTML = "Unauthorized!";
                    }
                }

                request.open("POST", "https://remotemanager.digi.com/ws/sci", true, "username", "password");
                request.setRequestHeader("Content-Type", "text/xml");

                request.send(xml);
            }
        </script>
    </head>

    <body>
        <form onsubmit="send_request(); return false;" method="POST">
            <input type="submit" value="Ping"></button>
        </form>
        <br>
        <br>
        <div id="response"></div>
    </body>
</html>

But I get:

OPTIONS https://remotemanager.digi.com/ws/sci 401 (Unauthorized)

test.html:1 Access to XMLHttpRequest at 'https://username:[email protected]/ws/sci' from origin 'null' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

So, if I'm performing the request form exactly the same computer, even the same folder, why does the C code works and the HTML/JS version triggers this CORS issue?

0

2 Answers 2

5

CORS (Cross-Origin Resource Sharing)

Simply allowing javascript to access any network resource is Not a Good Idea TM.

Usually javascript is downloaded from a server (not here but out there), but it runs locally (where all my private things are).

Originally the policy was to just allow the javascript to only talk to the server it was downloaded from. But this was a little restrictive and prevented/limited many useful things such as third party providers, and resource distribution networks, that weren't actually dangerous.

The solution is CORS, where the server returns the resource with header information describing who the javascript can work with (so javascript from two sites can work togethere), and which domains the javascript can interact with.

Native Programs (like Compiled C++)

Are local, and if you don't trust them you would not run them.

Therefore they can just talk to whomever they please.

The only exception would be restrictions imposed by the OS firewall, or network restrictions such as a proxy/firewall between your local network and the internet. You may have to provide additional credentials (such as the logged in user credentials) to get through.

2

Because that's not allowed in Javascript.

Javascript runs in a sandboxed environment; there are a lot of things you are not allowed to do there, such as write to the user's file system. You can write to the file system in C. The difference is that you won't be running your C program in millions of people's browsers.

If you have access to the server in question, use CORS to allow your Javascript to use it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.