Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can JavaScript communicate to a different server?

Can JavaScript interact with a database that lives on a different server?

I.e. there are three computers involved

  • A server : which gives an HTML page with JavaScript to
  • A client : which runs that page which wants to talk to
  • A second server : which sends and receives data to/from the client

Does this violate the Same Origin Policy? If not why not? If so is there a way around it?

My background - I'm a competent computer scientist but I've never dealt with client side programming. While answering feel free to use complex ideas but please assume I know nothing about the JavaScript language or the specific policies in place behind client-side programming.

like image 395
MRocklin Avatar asked Feb 19 '23 23:02

MRocklin


2 Answers

It does violate Same Origin whenever your html comes from server 1 and AJAX requests go to server 2.

Check out Cross Origin Resource Sharing. It is a standard designed to handle exactly this situation. It is implemented in most modern browsers.

Alternatively you can use JSONP to serve the data, or if you have no control of the second server, use a reverse proxy to proxy requests to the second server through the first.

like image 148
tobyodavies Avatar answered Feb 22 '23 22:02

tobyodavies


Yes, this violates the SOP. There are ways round it, but it's worth underlining a key point:

Any attempt from the client to access a remote server requires complicity on the part of that server.

So what are the options?

JSON-P

JSON-P involves having the server return a response wrapped in an invocation to a callback function. It works like this:

  • a new script tag is DOM-scripted into the page, or an existing one is reused
  • the script tag's src attribute is set as the request path (script tags can load scripts from anywhere - they are not subject to the SOP)
  • the server response with data, often (but not necessarily) encoded as JSON, and prints this out as an argument to an invocation of a callback function (which must be defined in your JS)

So a JSON-P request, written in native JS, looks like this:

callback = function(response) { console.log(response); };
var script = document.createElement('script');
script.src = 'http://www.some-request.com/here.php?callback=callback'; //the example happens to use the same name; the callback parameter tells the some-request domain what function to wrap JSON in 
document.body.appendChild(script);

Then, if the server's response was

callback({"foo": "bar"});

...we'd get the response in our console. Note I explicitly make the function global because it must be accessible and not hidden by scope. (In this sense it must be globally accessible, but not necessarily global in the traditional sense - it could, for example, be a static method of a global namespace).

Many JSON-P-complying web servers allow you to stipulate the name of the function you want it to call, normally by appending this info to the request URL via &callback=func_name.

More info on this here.

CORS / XHR2

In CORS, aka the cross-domain idea behind XHR (i.e. AJAX) v2, this will mean the server sending a header signifying which domains may make cross-domain requests to it - or all domains. In PHP, for example, we could allow any caller domain to make the request thus:

header("Access-Control-Allow-Origin: *");

More info on this here.

EasyXDM*

EasyXDM collates a number of vendor-specific and newer, HTML5-arriving means of posting and receiving text-based messages between domains, and is worth a look.

Non-JS

If you need to get something from a server that does not play ball, your only option is an intermediary server-side script, as these can fire cURL requests that can scrape a remote resource without the confines of the SOP.

$curl = curl_init("http://www.example.com/");
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($curl);

More on cURL here.

like image 23
Mitya Avatar answered Feb 22 '23 21:02

Mitya