Cross domain ajax

I’m trying to implement a cross domain solution for my rails app. I
want
people to be able to fill out a form on their site and the data will be
passed back to my site through ajax, and their site gets updated. I’m
looking for the best way to implement this. I would like to use a JSON
approach like yahoo does, but i’m not sure if it will work.

Though the form is pretty small (3 fields), one of them is a text field.
With the JSON approach, i would probably have to escape the whole text
field
and pass the values in the url like :

http://myrailsapp.com/controller/field_1_value/escaped_textfield_value/field_2_value

Will this limit the amount of data that i can allow for the text field?
Is
there a better way to do cross domain ajax? I want to just let users
include one or two scripts on their page and leave it at that.

Thanks in advance.

On 3/3/06, Manish S. [email protected] wrote:

I’m trying to implement a cross domain solution for my rails app.

AFAIK, you can’t. Browsers won’t allow it, as that would leave users
open to a major security hole.


Regards,
John W.


Alice came to a fork in the road. “Which road do I take?” she asked.
“Where do you want to go?” responded the Cheshire cat.
“I don’t know,” Alice answered.
“Then,” said the cat, “it doesn’t matter.”

  • Lewis Carrol, Alice in Wonderland

So, maybe this reveals too much about me, but I read your message too
quickly, and thought that “myrailsapp.com” was a “click here to see
what I’m talking about” kind of link, instead of a “you know, this
kind of URL”.

Except, it turns out that there is a “www.myrailsapp.com”.

Weird.

John is absolutely right. XMLHttpRequest calls can only be made
within the domain. that’s a restriction in the implementation and
there’s nothing you can do to go around that directly. however, if i
understand your intentions correctly, you can always make an ajax
call to the controller and have the controller do the talking to the
other domain and have it report back to your ajax call, no?

sebastian

I dont understand why you think you cant. Have you looked at yahoo’s
developer api’s? THey allow every web service to be called with
javascript
and the returned value will be a JSON object. This lets any web app
intergrate with their services. I think the security issue is there,
but if
you’re an honest service provider, you’re only going to integrate with
other
honest services. You cant force a web site to call your api
functionality
in hopes that your returned javascript will be able to do some damage.

yes i agree john is right about XMLHttpRequest. It does not allow calls
to
external domains. I’m NOT talking about using XMLHttpRequest. I’m
talking
about dynamic script tagging with javascript. This means dynamically
creating elements in the DOM to get third party
javascript. This is what the majority of ad services use. This is what
yahoo api uses if you request it. This functionality opens the
possibilities of interacting with other web services that regular XHR
does
not allow.

Here is a link you should check out if you still dont follow what i’m
trying to do.

http://www.theurer.cc/blog/2005/12/15/web-services-json-dump-your-proxy/

Have you used this with ruby on rails? I’m wondering if i shoul try to
make
this work with Action Web Services or just use

And define a route to an action that will split the url into @params.
Will
this work? I know this is limited by the maximum size of a url (2048 i
believe), but thats a lot of room for what i’m trying to do.

Have you checked out this class?

http://www.json.org/json.js

The yahoo page says it checks for valid json structure and could help
with
error checking.

On 3/4/06, Manish S. [email protected] wrote:

Have you used this with ruby on rails? I’m wondering if i shoul try to make
this work with Action Web Services or just use

Yes, I’m doing it on Rails, but I don’t think it really matters. It’s
just a bunch of custom JS to put on the client side first, but after
that, the rest is normal rails.

I’m not using edge rails, but I suspect you could use RJS and convert
it to JSON for digestion pretty easily.

http://myapp.com/controller/all/the/escaped/variables

And define a route to an action that will split the url into @params. Will
this work? I know this is limited by the maximum size of a url (2048 i
believe), but thats a lot of room for what i’m trying to do.

No reason to overwork the routing. You can pass parameters as part of
the query string as well.

Have you checked out this class?

http://www.json.org/json.js

The yahoo page says it checks for valid json structure and could help with
error checking.

Validating JSON wasn’t the problem. The trick is that the script tags
are evaluated right away. If the JS is invalid, the browser will
abort evaluation of the script. By using eval(), you can defer the
evaluation until you’re ready. But I dislike eval(), so I’ve made a
compromise – I send back an anonymous function as part of the remote
script. As long as there are no syntax errors, the JS will evaluate
correctly, and I can wrap the function (passed as an argument) with a
try…catch block.

You can definitely use dynamic script injection to facilitate
cross-domain requests. There’s some XHR plumbing that you will be
missing, so you’ll have to build it yourself. I ran across the
following challenges:

  1. Server errors (500, 404) disappear into the void. There’s no way
    to get the error code to know what happened to your request. My work
    around was to tag each request w/ a unique ID and trigger an onError
    handler when the timeout period expires. It’s probably about as good
    as you can do.

  2. Malformed Javascript will fail silently. One workaround is to wrap
    everything into a string using escape_javascript with a call like
    this:
    response_callback(<%= @id %>, “<%= escape_javascript(…) %>”);
    Since this is unlikely to be malformed, you can do the callback and
    know at least that there was a response. Then, using try…catch, one
    can use eval() to evaluate the script. If there are errors, you’ll be
    able to catch them.

Eval is kind of ugly though, the alternative is to make no errors :slight_smile:

  1. Limited to GET. This can be a problem for some things. I ended up
    using an IFRAME to POST data. Of course, since this is cross-domain,
    there’s no way to pass the info back. So I relied on using dynamic
    script calls to poll for a response. Ugly, but the only way I can
    think of making it work.

this might be a stupid question, but how do i access the query string?

if my url looks like:

http://myapp.com/controller/action?var1=foo&var2=bar&var3=blah

where does the stuff after the ‘?’ go and how do i access it?

It ends up in the @params instance variable.

I realize it probably is not optimal, but why not just write something
like in your controller?

def access

buf = “”
open( “http://remotesite.com” ){ |f| f.each_line {|line| buf += line }
}
send_data buf, :type => ‘text/html’, :disposition => ‘inline’
end

Now, in your javascript you can

Ajax.Request( “/controller/access/”, … );

To get access to whatever remote site you like.

There is even probably ways to optimize that remote site call… For
example, reading line by line is definitely not optimal… I would guess
mod_proxy would do a much better job…

-Todd

That approach works if the user’s browser is pointing at a domain that
you have control over. But in this scenario, unless I’ve interpreted
it wrong, the user’s browser is pointing at another site/domain that
is including the content (maybe via JS like the way that a lot of
advertisers do it). In this situation, he won’t be able to issue the
AJAX request because it would be cross-domain.

Although, one wonders – why not just use an iframe in this situation?