About cross-domain issue - ajax

If WCF REST Service is hosted in a different domain than the client-side pages (using basically HTML, CSS and Javascript), how are we able to consume this WCF REST Service ? I read an article which suggests using JSONP so as to circumvent the same origin policy. Basically on the client side when we make an ajax call we simply set dataType to jsonp, set jsonpCallback to some function name, contentType to application/javascript and set crossDomainScriptAccessEnabled to be true in Web.config. Is it correct ? Are there other ways ?

Related

How to allow API call only from the same origin/ domain?

So I have run into a problem. I am building a javacript file, which appends an iframe into clients page (within a div). Lets say, this iframe is loaded from http://example.com/iframe. iframe's backend module (to handle form submission; written in spring) has some endpoints like http://example.com/url1, http://example.com/url2
Now, I want only the iframe to be able to communicate with backend APIs. Currently, I can hit the iframe backend APIs from localmachine too.
I have come across the referer HTTP field, and initially was planning to set a referer filter on the APIs, but later found out that this can easily be spoofed. Will I get any benifit sertting CORS header on the APIs and setting the origin as http://example.com? Will it work, and if yes, is this a safe and dependable solution? Are there any better alternatives?

Is it necessary for Server to allow/configure CORS

I am trying to perform an AJAX request from my site which is deployed on 'HTTPS' protocol. but the request I am making to is deployed on 'HTTP' protocol.
So I am getting the following error:
This request has been blocked; the content must be served over
HTTPS
My Request is as follows:
$.ajax({
url: "http://testsite/service/process.php",
type: "POST",
data: { service: '#service', id: '#id' }
});
Is there any way/trick to bypass this error/issue without changing
anything at ServerSide (http://testsite/) or Is it necessary to
ENABLE/CONFIGURE C.O.R.S on Server Side because I have no controll over Server Side.
Alternatives to CORS
If your web application must run in browsers that do not support CORS or interact with servers that are not CORS-enabled, there are several alternatives to CORS that have been utilized to solve the cross-origin communication restriction.
JSONP. This is a technique that exploits the HTML script element exception to the same-origin security policy. Script tags can load JavaScript from a different domain and query parameters can be added to the script URI to pass information to the server hosting the script about the resources that you wish to access. The JSONP server will return JavaScript that is evaluated in the browser that calls an agreed upon JavaScript function already on the page to pass server resource data into your page.
OpenAjax Hub. This is an JavaScript Ajax library that allows integration of multiple client-side components within a single web application. Trusted and untrusted components to co-exist within the same page and communicate with each other as long as they all include the OpenAjax Hub JavaScript library. The framework provides a security manager to allow the application to set security policies on component messaging. Iframes are used to isolate components into secure sandboxes.
easyXDM. This is a JavaScript library that allows for string-based cross domain communication via iframes. It works on the same principals as OpenAjax Hub but does not have the security manager component.
Proxied Iframe. This do-it-yourself technique involves including an iframe on your page from the domain you wish to communicate with. This assumes that you are able to host pages on this other domain. The JavaScript running in the iframe serves as a rest proxy to the server containing the resources you wish to access. Communication between your application and the rest proxy will take place using post message. Post message is part of the HTML5 standard, but there is also a jQuery implementation for non HTML5-compliant browsers.

ie 10 cross domain ajax request

I have developed a web application that makes ajax requests to a web service on a server in a different domain from the server that hosts the web app.
I have configured the web service to do a pre-flight check to set the necessary headers to allow a cross domain request.
In the web app I am using a JQuery client to access the web service. I have set the properties on the Jquery command to allow cross domain access.
$.support.cors = true;
In Chrome this all works fine. In IE9, however the cross domain behavior is only partially successful. All get requests work. But post requests with a content-type of application/json fail because IE9 refuses to make post requests with any content-type except text/html. IE9 switches the content-type on the request and the request fails on the server with a 400 bad request.
I had read that with IE10 the cross domain request would work as in Chrome. But after just testing this, I find that IE10 has the same behavior as IE9. The browser will not set the content-type to application/json. So post requests fail.
Does anyone know whether it is possible in IE10 to do cross domain post requests with other content-types than text/html. This makes writing web apps that do anything more than display data extremely difficult.
Are there other settings I need to make on the Jquery request? Or in the service pre-flight?
What does your $.ajax() call look like? You could try adding data: 'json' to your JQuery call in order to force the data type to be json. You also shouldn't need to set $.support.cors = true;, JQuery should figure this out for you (but its ok to leave it in for now).
I do have the content type param set data: 'json'.
Chrome honors this but IE switches to text/html. I had read that this was a know issue in IE9 and below but that IE10 would be using the same ajax implementation as Chrome, but this is apparently not the case.

How to perform cross-site ajax request?

Browsers don't allow cross-site AJAX calls (it's a security restriction).
Is there any possible solution ?
EDIT
I control only the caller website
If you control both parties then there a lot of options. Such as JSONP, or modifying header responses of the remote website. Unfortunately, JSONP only works if the remote website supports it. You can't force a JSONP call to a website that doesn't already support it.
However, as you have said, you only control the source website. You cannot hack the browser around this restriction for obvious reasons. You do have a third option which is creating a back-end proxy. You can use Apache and mod_rewrite to create a proxy. Here is on how to do this or this link which is more detailed.
For example
ProxyPass /api/gtalkbots http://gtalkbots.com/reverse-proxy-data.php
ProxyPassReverse /api/gtalkbots http://gtalkbots.com/reverse-proxy-data.php
Creates a proxy at /api/gtalkbots which will returns the repose from gtalkbots.com
Your best solution is to use JSONP calls.
function jsonp(url, params, callback){
var script = document.createElement("script");
script.setAttribute("src", url+'?'+params+'&callback='+callback);
script.setAttribute("type","text/javascript");
document.body.appendChild(script);
}
function doit(data){
alert(data);
}
jsonp('http://domain.com', 'foo=bar', 'doit');
In the opposite side, the website you're contacting must be able to return a JSONP formatted response in order for this to work.
There are 2 ways to do this, depending on whether the callee will ship out JSONP or not:
1. If you can, use JSONP
JSONP is a way to bypass the cross domain policy by returning a function call, rather than a naked JSON object. The P stands for padding, essentially just the part that calls the function.
For this to work, the callee needs to return JSONP.
Regular JSON looks like this:
{a: 12, b: 15}
JSONP looks like this:
callback({a: 12, b: 15});
When the AJAX request completes, the callback function (which you define in your own code) will be executed and the JSON data passed to it as an object, thus bypassing the cross domain policy.
2. If JSONP is not supported, mirror the request through your own server
The second option is to pipe data through your own server. Your JavaScript makes a request from your server, and the server then mirrors that request to the remote server and pings back the result.
Since the AJAX request is now made to your own server you won't run afoul of the cross domain policy.
There are two downsides to this approach:
Two requests are now required which will slow the response time a little, though probably not much as server to server communication will probably be via a fat pipe.
Since all requests now originate from your server you may have problems with IP based rate limits. This is the case with Twitter API calls. You may be able to mitigate against this by caching results.

Controlling content type in a Restful web service

I am designing a Restful web service for an internal corporate application, and am curious how to merge JSON and "web content" requests.
The web application, like all good corporate applications, has a three-letter abbreviation that is reflected in the URL. Let's say that this application's "call sign" is abc, and the users access it at the following URL
http://servername/abc
When the users access the root of the application we want to serve them up the main html page, the .js files (including jquery), the css, and the images. Then, jquery will start to make AJAX calls back to the server.
What is the best way to handle these multiple content types?
http://servername/abc (returns contents of index.html)
http://servername/abc/javascript/jquery.js (returns a js file)
http://servername/abc/countries/de (returns JSON)
Should I split this into two web contexts? Should I use the jquery contentType parameter in the ajax calls to explicitly specify JSON versus HTML versus something else?
the jQuery contentType is really just a parameter that sets your content-type header on your HTTP request to the server. It is always a best practice to set these for your AJAX calls.
Added:
Another good practice is to specifiy the dataType parameter as that will set the accept header on your HTTP request. This is useful for both GET and POST AJAX requests.
Most, if not all, web service frameworks (Rails, ASP.NET MVC, .NET WCF, etc..) have abilities to examine the headers of an HTTP request and determine what type of content to serve back
for example:
application/json in an HTTP Header would let your webservice know to return a JSON response instead of an HTML or XML response.
Some of the better ways that I have seen web apps organized for HTML/JSON serving is to make your standard routes always serve your HTML pages and resources, ie:
http://servername/abc
http://servername/abc/javascript/jquery.js
would do exactly as you have said. For your JSON (or even XML) responses, I see folks create a route that is explicity understood to serve back those types of responses, ie:
http://servername/api/abc/countries/de
the url route begins with an /api/ which would always be understood to serve back a non-html JSON/XML response
this makes it pretty easy for your company to internally and externally understand that /api/ routes are your JSON/XML responses. It also makes it easier to expose these methods to your customers externally should you want to do that as the infrastructure is there, you would just need to authenticate, etc... the requests.
A good way to do this is to use the standard HTTP Accept Header. In your ajax requests, you would specify this header to be application/json, and then all other web requests would include the browser's accept headers. Then, on the server side, you could use the Accept header to determine which content to serve.
If you use JQuery, then the Accept header will be set to application/json automatically if your dataType parameter is set to "json."

Resources