2

Am working in Mobile App develoment using HTML5 + Phonegap. Currently am working a mobile App using XMLRPC and its working fine. (Android and iOS)

I need to work the same application as a website in browsers. (using HTML5). But when am trying to Run my application on website i am getting this error :

XMLHttpRequest cannot load 'Client' URL'. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost <http://localhost/>' is therefore not allowed access. 

When am search experts says that use JSONP. But using same XMLRPC method can i work it ?

For example ;

For a Login purposes am using ;

$.xmlrpc({
  url: 'http://clienturl/xmlrpc/common',
  methodName: 'login',
  params: [Database_name','user_name','Password'],
  success: function(response, status, jqXHR) {
    alert('success'); },
  error: OnError
});

Its working fine as a Mobile Application.

But gets Access-Control-Allow-Origin cross domain issue when i am trying to run as a Website.

How can i fix this ?

ULLAS MOHAN.V
  • 1,521
  • 1
  • 19
  • 36
  • Updated my answer. Don't use the *, if your service is a private one with authentication, because it would be a security risk... You have to generate the allow origin headers by every request instead. – inf3rno Aug 22 '14 at 15:26

1 Answers1

1

By default the SOP (same origin policy) allows cross-origin requests, but it prevents receiving the responses of those requests. The Access-Control-Allow-Origin in your error message is a CORS (cross-origin resource sharing) header. It tells the browser that you allow reading the responses of a domain (your XMLRPC server's domain) by sending requests from another domain (your XMLRPC client's domain). So you have to send back CORS allow headers from your server if you want to call it with AJAX.

note: CORS won't work in old browsers.

Possible solutions:

  • If you call http://clienturl/xmlrpc/common from http://localhost then the

    response.header('Access-Control-Allow-Origin', "*")
    

    is one not so secure solution according to this: Origin http://localhost is not allowed by Access-Control-Allow-Origin But you can always add another hostname (e.g. http://client.xml.rpc) for your client, for example by windows you can modify the hosts file and add a binding using the IIS server.

    I don't recommend this solution, because it is a security risk with the allow credentials header.

  • Another more secure options is to make a list of allowed hosts, check from which host you got the actual request, and send back the proper header:

    if (allowedHosts.contains(request.host))
        if (request.host== "http://localhost")
            response.header('Access-Control-Allow-Origin', "null");
        else
            response.header('Access-Control-Allow-Origin', request.host);
    else
        response.header('Access-Control-Allow-Origin', server.host);
    

    This is the proper solution with multiple hosts, because if you allow credentials for *, then everybody will be able to read and write the session of a logged in user.

    By http://localhost and file:/// IRIs you have to use the null origin. I am unsure about other protocols, I guess in the current browsers you have to use null origin by them as well.

Community
  • 1
  • 1
inf3rno
  • 24,976
  • 11
  • 115
  • 197
  • Where i can add this response.header('Access-Control-Allow-Origin', "*") ? – ULLAS MOHAN.V Jun 03 '14 at 09:59
  • Please tell me more about what domains, sub-domains you use for development and production (I don't need the exact domain names, just a list of where your server and where your clients are relative to each other). – inf3rno Jun 03 '14 at 10:13
  • am using two servers. one for server and other for client. server : http://50.57.44.100:7069/xmlrpc/ client : http://ups.test.net/ – ULLAS MOHAN.V Jun 03 '14 at 10:27
  • You have to add the header to the server responses and you have to allow the client's domain in that. It is possible to add a list of exact domains instead of *, but current browsers support only a single exact domain name. This is a security risk, read more about it [here](http://stackoverflow.com/questions/12001269/what-are-the-security-risks-of-setting-access-control-allow-origin). You have to add some [security headers](http://stackoverflow.com/questions/12001269/what-are-the-security-risks-of-setting-access-control-allow-origin) and use * only for temporarily until you dev on localhost. – inf3rno Jun 03 '14 at 10:35
  • Or maybe send back different responses if there is a dev api key present. We usually put all of these headers into a webserver config file, for example .htaccess. This is the easiest way, but you can add them to your server side application as well. – inf3rno Jun 03 '14 at 10:37
  • Btw. it is strange that you did not run into this by your mobile client... Maybe it wasn't mobile browser based... – inf3rno Jun 03 '14 at 10:38
  • Here is the browser support of CORS: http://caniuse.com/cors . If you have problems with this, then you have to put the client under the same domain (and sub-domain) with the server. – inf3rno Jun 03 '14 at 10:41
  • I updated my answer. It was only about static headers, but for example by apache htaccess, or by every server side language you can set the allow origin by checking the host of the request. So it is possible by dynamically generated headers to allow multiple pages without any security risk. This is important because allow origin * with allow credentials true will allow any attacker to still profile data, and maybe even modify passwords... – inf3rno Aug 22 '14 at 15:02