44

I'm making a RESTful web service call in my JavaScript page and get the following warning:

"This page is accessing information that is not under its control. This poses a security risk. Do you want to continue?"

Now I've read up on this and am aware of the cross-domain, same origin policy. However, I don't get such warnings when I consume other APIs like Google's Maps API. Clearly the domain is not the same as my local domain. What is the difference?

My initial guess is that Google is 'imported' into the page using the <script> tag while my REST consumption is using XMLHttpRequest. IF that is the case, what is the difference between these two approaches that one would merit a warning and the other not?

Jordan Parmer
  • 36,042
  • 30
  • 97
  • 119
  • Get a tool such as Fiddler2 and watch the magic – epascarello May 29 '09 at 14:11
  • This didn't really work for me. I tried it, and still got denial of permission errors in chrome and firefox. – Merritt Jan 29 '10 at 20:53
  • @Merritt - You'll have to debug this in parts. If you browse to your proxy page in a web browser, do you get text back whose contents are the JavaScript call? – Jordan Parmer Feb 01 '10 at 15:43
  • I looked into this extensively last week and found out the only real way to accomplish this is to use JSONP. You can actually accomplish this relatively easily, if you can get the webservice to return jsonp instead of just json. This code project shows how to do this: ttp://www.codeproject.com/KB/webservices/ASPNET_JSONP.aspx – Merritt Feb 05 '10 at 20:12
  • @Merritt - Yes, that is correct. Sorry, I should have put that up in my reply. I just manually padded the JSON since it is pretty simple to do. – Jordan Parmer Feb 05 '10 at 22:33

2 Answers2

7

The following might explain things: http://markmail.org/message/5wrphjwmo365pajy

Also, they employ some script hacks (e.g. inserting a script into the DOM to get requested data, instead of XHR).

Michał Perłakowski
  • 88,409
  • 26
  • 156
  • 177
Jonathan Fingland
  • 56,385
  • 11
  • 85
  • 79
  • thanks for pointing that out. obviously their technique could be made more useful by taking query string paramaters to make it more relevant in most cases. – Jonathan Fingland May 29 '09 at 23:08
  • For possible work-arounds, see Rook's answer to http://stackoverflow.com/questions/1131210/work-around-for-the-same-origin-policy-problem – jsalvata Sep 17 '12 at 12:54
1

I would like to summarize what the solution was to this problem.

Essentially, you inject code through the pages <script> tag when importing JavaScript. Anything imported through this tag is executed immediately in the global context. So instead of passing in a JavaScript file, pass in a URL to a website that returns a page not of HTML tags but instead a page that returns JavaScript code text that calls a callback in your code.

You use URL parameters to tell the page what 'callback' to return and any parameters that need to go into the callback. For instance:

<script type="text/javascript" src="http://crossdomainhost/CrossDomainConsumerSite/Default.aspx?callback=myCallback&param1=myParam"></script>

When this is evaluated, the page content returned by the 'src' parameter is:

myCallback( myParam );

On the server side, you will create a site at that URL that overrides the OnLoad equivalent (with whatever server-side language you are using). Instead of page HTML, the OnLoad will take the URL parameters and re-swizzle them to match the callback call above.

When the substitution is made, the callback is immediately called when the client loads the page. The benefit of this is that the 'src' URL doesn't have to match the domain of the hosted page.

Here is what the client HTML page will look like at the end:

<script type="text/javascript">
    var myCallback = function( myParam ) {
        alert( "this was called across domains!" );
    };
</script>
<script type="text/javascript" src="http://crossdomainhost/CrossDomainConsumerSite/Default.aspx?callback=myCallback&param=myParam></script>
sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
Jordan Parmer
  • 36,042
  • 30
  • 97
  • 119