Our Client requires that we supply Widgits for their site. They want to link to us to get Html & the jQuery required to manipulate the Html and do asynchronous requests. I understand that there are cross-domain security limitations that would prevent this from being a possibility, but that some of those limitations are aleviated by using JSONP as the data transfer format.
I'm finding it difficult in finding an explanation of what's possible in the context of what I'm trying to achieve. Could somebody please fill me in?
In short, all AJAX requests (and cross-window scripting) are subject to the Same Origin Policy. JSONP (JSON with Padding) isn't subject to the Same Origin Policy because it involves adding a script from an external domain to the DOM, the script itself contains a call to a known function that already exists on the client, with the JSON as the function call's argument.
JSONP can't return HTML or XML directly, but it could pass an object that contains a string of HTML or XML data, which in turn could be added to the DOM or parsed by the client.
For instance, a JSONP might return:
jsonp_callback({"Errors":"none","Data":"<div id='externalWidget'>Hello!</div>"});
When this script is added to the page, the function jsonp_callback will be executed with the JSON object as its argument. That function would then add the HTML code to the page.
There are other ways of achieving what you want. For instance, if the client doesn't need to manipulate the data in any way, you could provide a widget via a HTML document that would be iframed by your client's page:
<iframe id="widget" src="http://mysite.com/widget/v1/" />
If they did need to manipulate the data, they would blocked by the Same Origin Policy as outlined above.
As far as I know, JSONP utilises SCRIPT tags to load content that is external to the domain that your calling page is being loaded from. Using a SCRIPT tag allows you to reference external URLs. Once this external 'script' has been loaded, data will be returned to a specific callback function which was passed through the location of the external script.
jQuery: http://www.insideria.com/2009/03/what-in-the-heck-is-jsonp-and.html
MooTools: http://www.clientcide.com/wiki/cnet-libraries/06-request/00-jsonp
It sounds like you could use easyXDM ( http://easyxdm.net/ ) for your purpose.
Its a library that gives you cross-domain messaging and RPC.
You can easily use it to set up an iframe based widget (like the one the build int Widget class does http://consumer.easyxdm.net/current/example/widgets.html) or use it only to get raw data.
You can also take a look at the xhr sample that gives access to cross-domain ajax at http://consumer.easyxdm.net/current/example/xhr.html, or the generic RPC sample at http://consumer.easyxdm.net/current/example/methods.html
Related
There is a page: http://renren.com/echo (not real) that will return JSON style data like:
{"candidate":[{"id":251574647,"name":"Jack"}]}
Now I'm at http://my-server.com and I'd like to do a cross domain Ajax request.
Due to the page at http://renren.com have to be log-in ed to view, I can't use server proxy.
The returned JSON data doesn't have a function call or assignment, so I can't use JSONP.
I doesn't have the right to modify the page at renren.com. What can I do in this condition?
The technique described by Brian Chess et. al. in the following paper might be of use in this case. In short you override the javascript setter that is used to process the incoming JSON.
https://www.fortify.com/downloads2/public/JavaScript_Hijacking.pdf
When the JSON array arrives on the
client, it will be evaluated in the
context of the malicious page. In
order to witness the evaluation of the
JSON, the malicious page has redefined
the JavaScript function used to create
new objects. In this way, the
malicious code has inserted a hook
that allows it to get access to the
creation of each object and transmit
the object's contents back to the
malicious site.
I don't think you can do much without a proxy page or having control of how the data is returned.
You can use Apache's mod_proxy to perform this request under the guise of your domain. Configure a URL such as http://my-server.com/renren as a proxy for http://renren.com/echo.
When this is complete, you can send your AJAX requests to http://my-server.com/renren and avoid the cross-domain limitation.
If you're on cross-domains, you cannot rely on AJAX. You'd have to use a cURL type of a call through your own PHP/ASP scripts to call for data from another domain's files.
I am looking to create a widget similar to the one created by Get Satisfaction (http://getsatisfaction.com/). You can see their widget by clicking on 'Feedback' on the left side of the page.
We would like the user to be setup by copying a bit of JS to their webpage and nothing else.
In its simplest use, a user would open the widget and enter data. This data would be sent to our server (cross domain) for processing and a response sent back to the user.
Can anyone shed some light on how this can be done?
I've read that I can send a JSONP request using jQuery and handle a response callback- can this be encapsulated with injected javascript?
All help greatly welcome.
Regards
You are correct, JSONP is the correct method for this and should work for your situation. JSONP is basically injecting a <script> tag to simulate a GET response, the contents of the script is a callback method with the JSON object inside it. Hense the name, JSON + Padding.
Note: JSONP does obviously not support POST callbacks or custom headers, as it is just a <script> tag that gets injected and removed when ready.
in my JS project I need to load data from cross-domain. (JavaScript sits on domain A, the data comes from domain B)
I have a solution that uses JSONP but I really need to load an XML instead (ordinary XML music playlist). The main goal is to be able to load and parse the XML data without the need to modify them first to some other format (like JSONP).
Is it completely impossible? Or are there any workarounds or hacks?
I am targeting mainly the latest browsers mainly on iOS.
Thanks!
PS: Could easyXDM be of any help? Or it's not relevant to XMLs?
UPDATE: unfortunately I can not use proxy, I am really asking about a direct solution.
You can totally do this, just have your domain B return something like
func("<myxml></myxml>");
or
var someVar = "<myxml></myxml>";
The name JSONP doesn't really have anything to do with JSON specifically since its concept is all about executing JavaScript that has your data embedded in the code.
Once your domain B returns exactly one of those 2 forms above, domain A can simply use it either by doing:
<script>
function func(xmlString) {
alert(xmlString); // you can parse the xmlString with
// jQuery or something else
}
</script>
or if you use the second example:
<script>
alert(someVar);
</script>
The usual solution is to have a "AJAX proxy" - a simple server-side script running on your domain, that fetches the data from the other domain and returns it unchanged.
The simplist is to give the script the URL you need the data from:
http://example.com/proxy.php?url=http%3A%2F%2Fexample.org%2Fajax%3Fid%3D123 gets the data from http://example.org/ajax?id=123
This can however be misused if you let any URL be fetched like that, so you should have your script, check that it actually only gets data from a specific URL.
In order to avoid having to parse the URL to check this, you could write a proxy specificly for your app, that only accesses the specific resource you need:
http://example.com/proxy.php?id=123 to access http://example.org/ajax?id=123.
If you have a JSON-P solution in place, you can just pass the XML to the JSON-P callback as a string. You can then do XML parsing of a variable string in JavaScript
The whole idea with JSONP is that the response must be executable as script. So sure, you can pass XML data back, as long as it's valid Javascript - for example, the server could wrap its response in a string:
myCallback('<xml><stuff/></xml>')
and you'd have to parse it with jQuery:
success: function(data) {
var xml = $(data); // now do stuff
}
This assumes that you control the other server and/or someone who does is interested in formatting their data that way. Otherwise, you're out of luck, and need a proxy of some sort - you might be able to do this with YQL.
http://www.diigo.com/tools/diigolet
Diigolet essentially allows you to use a bookmarklet to bookmark sites. With the bookmarklet I'm making, I also need to pass the current URL of the site the user is on to my server. Everytime I try this, I get a cross-scripting error.
Does anybody know how to bypass this like the diigolet?
Essentially, they work around the same-origin policy by injecting a script tag with the different-domain URL rather than using an XMLHttpRequest. Note that this is different from a normal JSON request in that the JSON is wrapped in a callback function, for example:
myCallbackFunction(<JSON here>);
(This works because JSON is a subset of JavaScript's object literal notation.)
In their case, they hardcode the name of the callback function as diigolet.callback, but there exists a specification called JSONP that JavaScript libraries such as jQuery support.
Under the JSONP specification, the name of the callback function is passed to the server via a callback=myCallbackFunction parameter in the GET request. Your server-side code needs to handle this appropriately to be able to handle JSONP requests from jQuery.
Here's the problem:
1.) We have page here... www.blah.com/mypage.html
2.) That page requests a js file www.foo.com like this...
<script type="text/javascript" src="http://www.foo.com/jsfile.js" />
3.) "jsfile.js" uses Prototype to make an Ajax request back to www.foo.com.
4.) The ajax request calls www.foo.com/blah.html. The callback function gets the html response and throws it into a div.
This doesn't seem to work though, I guess it is XSS. Is that correct?
If so, how can I solve this problem? Is there any other way to get my html from www.foo.com to www.blah.com on the client without using an iframe?
It is XSS and it is forbidden. You should really not do things that way.
If you really need to, make your AJAX code call the local code (PHP, ASP, whatever) on blah.com and make it behave like client and fetch whatever you need from foo.com and return that back to the client. If you use PHP, you can do this with fopen('www.foo.com/blah.html', 'r') and then reading the contents as if it was a regular file.
Of course, allow_remote_url_fopen (or whatever it is called exactly) needs to be enabled in your php.ini.
There is a w3c proposal for allowing sites to specify other sites which are allowed to make cross site queries to them. (Wikipedia might want to allow all request for articles, say, but google mail wouldn't want to allow requests - since this might allow any website open when you are logged into google mail to read your mail).
This might be available at some point in the future.
As mentioned above JSONP is a way around this. However, the site that you are requesting the data from needs to support JSONP in order for you to use on the client. (JSONP essentially injects a script tag into the page, and provides a callback function that should be called with the results)
If the site you are making a request to does not support JSONP you will have to proxy the request on your server. As mentioned above you can do this on your own server or what I have done in the past is use a http://www.jsonpit.com, which will proxy the request for you.
One option is to implement a proxy page which takes the needed url as a parameter. e.g. http://blah.com/proxy?uri=http://foo.com/actualRequest
JSONP was partially designed to get around the problem you are having
http://ajaxian.com/archives/jsonp-json-with-padding
JQuery has it in their $.getJSON method
http://docs.jquery.com/Ajax/jQuery.getJSON
The method shown above could become a large security hole.
Suggest you verify the site name against a white list and build the actual URI being proxied on the server side.
For cross domain hits this is a good working example and now is considered as some what "standard" http://www.xml.com/pub/a/2005/12/21/json-dynamic-script-tag.html.
there are other ways as well, for eg injecting iframes with document.domain altered
http://fettig.net/weblog/2005/11/28/how-to-make-xmlhttprequest-connections-to-another-server-in-your-domain/
I still agre that the easy way is calling a proxy in same domain but then it's not truly client side WS call.