|
CrossXhr
Cross Domain XHR: A drop-in replacement for XmlHttpRequest object
Moved to Git HubThe source code has moved to git hub http://github.com/borisreitman/CrossXHR IntroductionStandard ajax does not allow cross-domain requests. CrossXHR is a drop-in replacement for XmlHttpRequest object. Demo: http://random.hypervolume.com/crossxhr.html UsageJust place crossxhr.js and crossxhr.swf in the same web location, and then in your html page add: <script src="http://www.somedomain.com/path/to/crossxhr.js"></script> In your javascript, create the xhr object like this: var xhr = new CrossXHR(); You can host crossxhr library files under one domain, and use for pages under a different domain. Note: Just like the plain XmlHttpRequest object, CrossXHR can return any kind of content, text or xml (not just json or javascript like some other competing solutions). crossdomain.xmlIf you plan to do an XHR request to domain www.xyz.com, make sure that http://www.xyz.com/crossdomain.xml exists. Here is a sample crossdomain.xml: <?xml version="1.0"?>
<!DOCTYPE cross-domain-policy
SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<allow-access-from domain="*" />
</cross-domain-policy>How it worksCurrently, this is implemented using Flash and requires flash to be supported in the browser to work. A 1-pixel transparent flash is embedded in the top-left corner of the page. Using with other librariesJust edit the source code of a library slightly to use CrossXHR instead of XmlHttpRequest object. For example: Prototype AcknowledgmentsJulien Couvreur has come up with this concept. Donations |
Nice library, very much like the flXHR (http://flxhr.flensed.com) I've had out there for awhile. A few things to point out that I learned in the creation of flXHR that you may want to consider:
1. Sometimes people need to be able to specify a different location for the security policy file. Having a configuration value for that is important.
2. Flash has, in my opinion, an important security hole that must be addressed with projects such as this. I note it in this blog post:
http://www.flensed.com/fresh/2008/08/adobe-flash-player-security-hole/
Basically, the gist of it is that the plugin only enforces security policy on the swf-domain (that is, the domain where the SWF comes from). For a normal compiled SWF, that's usually fine. But when a SWF like the ones we use for solutions like this has to open itself up to javascript control so completely, now the file can be linked to and used on a page-domain other than where the SWF came from, and thus can be abused and used for evil. And the plugin gives NO way for a server policy file to control what page-domain (in the address bar of the browser) can use flash to communicate with it. There is an auto-trust of a SWF back to its origin domain, and so anyone who hosts such a file on their own server is subject to someone linking to it and abusing it.
I note in there that I wrote an AS3 class for checking the policy against both the swf-domain and page-domain, to plug this hole. I consider this to be a vital part of keeping the flash solution from being misused.
3. Also, I chose to pin my object to requiring flash 9.0.124 (not just 9.0.0) because Adobe's security model was very immature and open to exploit until .124. You might want to read up on some of the ways that early 9.x plugin versions have been hacked.
4. You are using swfobject 2.0, which is good, but 2.1 solved LOTS of issues, especially memory leak and performance issues. In addition, 2.2 is just about to come out, it's in beta right now (I am on the dev team for SWFObject as well). You might want to consider upgrading to 2.1 or 2.2beta.
5. I'd recommend finding a way around using "document.write". This makes your library only useful if people can statically include the .js file in the page, which a lot of dynamic mashups cannot. Again, SWFObject 2.2 is fixing a lot of issues with being dynamically added to pages, so consider looking into it.
6. You should consider exposing some of the other API for XHR, such as setting of request headers. A lot of Ajax apps need to be able to do this, and a lot of frameworks expect to be able to call such methods on an XHR-clone object like yours.
All in all, good project. Nice work. I'd be interested to know what parts of flXHR you have either looked at or weren't happy with in the creation of this library. I hope we can learn from each other on it. :)
It's funny -- a year ago I was looking around for a solution like flXHR or like this project, but couldn't find one. So I wrote my own and only got around to publishing it recently. And now I find your project and a few others that do the same thing.
Also, replacing native XmlHttpRequest? object is not a good idea, because if you embed a gadget in a third party site, you don't want to screw-up their javascript code.
I agree about the headers.
I don't replace the native XMLHttpRequest object. I simply created (as did you to some extent) an object that has an identical API to that object, which means it can be used in place of native XHR. One of the demos (#7f) on http://flxhr.flensed.com/demo.php does show how you can literally replace the native XHR objects if you want to, but it's just extra demo code, not something that happens as part of normal flXHR usage.
The only time I advocate such drastic replacing of the object is if you are on a page using some framework (like DWR for instance) which presents no way to "adapt" it to use flXHR, as it's hardcoded to try and use native XHR. So, you can still use such frameworks by simply forcing the DOM to have flXHR as a replacement.
Thankfully, other frameworks like jQuery and Dojo have adaptable "factory" functions which can be adjusted at run-time (rather than hacking the library source) to use flXHR. In fact, for jQuery and Dojo, I have "plugins" I wrote which adapt those libraries to use flXHR in an intelligent way, with an XHR "Registry" that gives good flexibility and configurability.
Hi,
I am new to web development using flash. Could you please help me out here?
I am trying to make this demo to work with other web site like yahoo or Google search. Is it possible to do it?
The URL defined in the demo is working fine but I could not make it work with any other URLs:
URL defined in the demo: http://search.yahooapis.com/ImageSearchService/V1/imageSearch?appid=YahooDemo&query=Madonna&results=2&output=json
For example the following is not working:
http://search.yahoo.com/search?p=cross+domain&fr=yfp-t-501&toggle=1&cop=mss&ei=UTF-8
Thanks in advance.
Another suggestion for this project: It appears to me that you only use one instance of the flash object in the page, which is probably for load-time/memory management purposes. But what I've found is that a single flash instance can't do a very good job of dealing fully parallel in simultaneous requests. flXHR puts one flash instance for each object instantiated, which allows all the requests to truly be in parallel.
Peter, this is because the url that you access must be permited to be accessed on the server using crossdomain.xml file. The crossdomain.xml file lists what is allowed to be accessed.
xmlhttprequest has sync mode. how can the crossxhr be in sync mode?
Is there any way with this script to make sure that the XHR requests are queued? Like so that if a bunch of XHR requests are made quickly, only one at a time will happen, and they'll happen in order? Thanks!
Ryan, they are already queued. Leung: I think it already works like that. It takes all the same options such as xmlhttprequest, and this whould be the third option to open() call. If it doesn't work like that now, it should be modified.
It does not support headers. If I want to make a soap call, how am I going to set specific headers for my request?
Mihai, it is not hard to modify the source. Just on a function setHeader on js side, and propagate it to the flash side.
should it work if crossxhr.js/swf are accessed via https instead of http? I see that my browser gets both files successfully via https too ... but this seems to kill it: request.open('POST','https://myserver/somepath');
If crossxhr.js/swf were retrieved via http, then the POST to the https://... works fine.
some additional: diving into this request.open function then firebug shows the following as the last or better "dying" execution: gateway.create(this.id, method, url);
this does not work with FF4
If you use https for the external domain to call, the callback reports status=0. I cannot find any answers on how to use https, any one have any thoughts?
Update:
I have moved the source code to Git Hub, and also fixed the demo (yahoo took down their ajax search api).
I have reverted to an earlier version of the code, before modification required to make the comet interface work.
I haven't tested "https" support, contributions are welcome. Use the code on Git Hub as your starting point.
http://github.com/borisreitman/CrossXHR
The demo page doesn't work on IE8 :(
how can I set response content-type to text/xml, so I can get responseMXL instead of responseText? thank you.