Why does my web service call fail when calling a different site - ajax

I am making a JQuery ajax call to a web service like so:
$.ajax({
type: "POST",
url: "https://WebsiteName.com/Service.asmx/LoginExternal",
data: "{loginData: " + JSON.stringify(LoginData) + "}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
... Stuff ...
},
error: {
... Error Alert ...
}
});
When I am on the actual web site, this succeeds. When I am on localhost and use a relative path, it succeeds. However, when I am trying to access the web site (using an absolute path) from localhost, I get the error message that the call failed.
This would seem to indicate that it is a permissions problem and I've made sure that the web.config doesn't require authentication for access to the web service but I'm not sure what else to check. Any help would be greatly appreciated!
Update: The "thrownError" that I am getting is "No Transport" - hopefully that helps.

Security:
http://en.wikipedia.org/wiki/Same_origin_policy

Being an unsecured scripting logic, ajax requests made using JavaScript (or JQuery) are stucked on same host, protocol and port, due to unauthenticated and unencrypted requests.
A method for passing requests to a different host, you must implement a bridge service written in a secure language (ex. Java), deployed on same host that passes your requests further to your services, and then passes response to your ajax call.
Your ajax call will be on the bridge service then.

Related

Send POST AJAX request from Office Add-In

I'm trying to send POST Ajax request for third party service from my Outlook Add-in, but no matter what I tried I receiving Error: Access is denied, and status 0 (request never hit the server).
Assuming we are running IE9 or 8 behind the outlook I tried old school hacks like https://github.com/MoonScript/jQuery-ajaxTransport-XDomainRequest.
$.ajax({
url: endpoint,
data: JSON.stringify({'1':'2'}),
// headers: {'X-Requested-With': 'XMLHttpRequest'},
contentType: 'text/plain',
type: 'POST',
dataType: 'json',
error: function(xhr, status, error) {
// error
}
}).done(function(data) {
// done
});
Is there is something more I need to implement? Of cause I add my domain to manifest AppDomain property.
Cheers
The following needs to be done to send request to 3rd party service ...
Add the service URI to AppDomain list (you've done it.)
The service MUST have SSL endpoint; "https://your.domain" must be included within of "AppDomain" entry (see above)
The service has to allow CORS requests for your application (hosted Outlook App URI) domain or any domain. This is up to the service creators to allow or disallow client apps connections via Ajax.
As of observation of your code I notices you are sending JSON object, but setting content type to "text/plain". Contact the service creators to get information on what type of the data they accept as request. Usually services allow "application/json", but not plain text.

Access response data in JSONP request

I have a SAP Gateway OData-Service and a local Tomcat Apache Server. My SAPUI5 Client is deployed in the Tomcat and requests a OData-Webservice from the SAP Gateway remote server. In fact there is a cross origin domain error. So I set the header "Access-Control-Allow-Origin" in my OData-Webservice and my SAPUI5 client requests with JSONP, but I will get an error because the SAP Gateway can't handle with JSONP responses.
My code:
The error: "Uncaught SyntaxError: Unexpected token :"
The error depends on the incompatibility of the SAP Gateway to JSONP.
If I look in the network requests I will find this one:
It is the JSON (not JSONP) response from the webservice.
So my question. Is there a possibility to access to this response?
I tried to access via a lot of callbacks like success, error, fail, done, always, complete, and so on. But no chance...
thanks and best regards
$.ajax({
type: 'GET',
url: url,
async: false,
jsonpCallback: 'jsonCallback',
contentType: "application/json",
dataType: 'jsonp',
success: function(response) {
//this is where you'll get data/response
console.log(response) ;
},
error: function(e) {
console.log(e.message);
}
});
Update:
Problem is with your context.. there is some value like _1453458442107=:1
Check that and encode it.
If you set the CORS header "Access-Control-Allow-Origin" in the odata responses you should be able to access the service with regular JSON (without the P).
JSONP is a workaround to circumvent the same origin policy when the CORS-Headers are not available.
If your odata service uses authentification it might be necessary to set some more CORS headers to get it working.
On MDN you can read more about CORS and its headers.
On Wikipedia is a chapter about CORS vs JSONP.
So have you tried something like the following?
$.get({
url:"https://.../sap/opu/odata/sap/ZMOBILAD_SRV/UsernameSet?$format=json",
context: document.body,
cache: false
}).done(function(){
console.log(this);
});

CORS could not get fixed even after adding Access-Control-Allow-Origin in service

I tried to access a Rest service which was hosted in different domain from mine through an ajax call and I got "CORS" error in the firebug.
After researching about this problem, I figured out that the service needs to be changed by adding Access-Control-Allow-Origin to * in the response header. I did that in the service as well.
public Response search(String expression) {
return Response.ok() //200
.entity(ConnectionUtils.query(expression))
.header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT")
.header("Access-Control-Allow-Headers", "Content-Type,Accept")
.allow("OPTIONS").build();
}
Above method is the implementation class of below service interface:
#POST
#Path("/search")
public Response search(String expression);
I tried to post a request to this url through chrome advanced rest client, I am getting the response as well. Also the response header shows that the Access-Control-Allow-Origin has been set properly as well. Please refer to below screenshot of chrome client:
If you see above, the response headers has been changed.
But my below ajax call always return CORS error:
"Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://192.168.1.100:8080/cqs-1.0-SNAPSHOT/services/services/cqs/search. This can be fixed by moving the resource to the same domain or enabling CORS."
$.ajax({
type: 'POST',
url: "http://192.168.1.100:8080/cqs-1.0-SNAPSHOT/services/services/cqs/search",
crossDomain: true,
dataType: 'json',
data: {"offer.offer.offerId.USSellerId": {$gt: 0}},
headers: {
"Accept": "application/json",
contentType: "application/json"
},
success: function (data) {
console.log(data);
},
error: function (data) {
console.log(data.statusText);
console.log(data.name);
}
});
Don't use CORS. It's fraught with peril. Rather, set up a simple reverse proxy on the server using Apache (or similar). Once you set it up, all requests from your app can go back to your domain/port thus not triggering any OPTION methods from the browser. Meanwhile your reverse proxy can redirect requests based on the path in the url, which is completely up to you on how you want to configure.
In my case, I just had a simple case of needing to access 2 different ports on the same server. Port 8080 (tomcat) was serving my GWT UI and REST requests from my GWT pages (using RestyGWT) were needing to hit port 9000 (Play framework port). Due to the different ports, CORS was required to deal with the OPTION 'preflight' checks that the browser was doing.
To solve this I just setup my URLs as having either /ui path or a /api path.
Since the domain/port was the same, and my proxy could easily redirect transparently to the correct port (api -> 9000 and ui -> 8080) there was no longer any need for CORS.
CORS has a lot of issues in my experience including cookies. It's really better to avoid it using a reverse proxy.
If you need more details, I can post more - let me know.
JR

How do I make a Cross-Domain Request in Firefox?

I am using the following jQuery AJAX call to access a SOAP Web Service:
jQuery.ajax({
url: url,
type: "GET",
dataType: "jsonp text",
crossDomain :true,
data:"i="+'a'+"&j="+'b',
processData: false,
success: OnSuccess,
error: OnError
});
This code works fine in IE but it get an empty response in Firefox. On further searching it seems Firefox does not allow cross domain requests by default, or it processes the header information differently.
My application is on localhost:8081, and the WebService I want to consume is on localhost:8080. Is there any way I can allow Firefox to make a cross domain request?
See https://developer.mozilla.org/en-US/docs/HTTP_access_control
ya, This issue is resolved after I installed CORS add-on for firefox. But is there any other way, I can set the parameters using JQuery-ajax code?
you need send "Access-Control-####" headers same what in OPTIONS request response.

Access to restricted URI denied" code: "1012

On domain A (localhost:8080) I run this code to access an unauthenticating REST serivce on domain B (localhost):
req = new XMLHttpRequest();
req.open('GET', 'http://localhost/rest/service');
req.send();
This works fine and I do get my response across domains as I have Apache on domain B set the response header:
Header set Access-Control-Allow-Origin "http://localhost:8080"
However if I now turn on authentication for the REST service and try to run the same request:
req.open('GET', 'http://admin:admin#localhost/rest/service');
It now produces this error in Firebug:
Access to restricted URI denied" code: "1012
I'm confused that I am able to sucessfully make cross domain ajax calls to the authenticated service bypassing the same origin policy, yet when authentication is required on the service Firefox decides not to allow the ajax call? How can I fix this without using jsonp etc, as the production server won't be able to provide PHP or Servlet hosting.
It's easy with JQuery 1.5+, which I recommend you use for your JavaScript solution:
$.ajax({
url: 'http://admin:admin#localhost/rest/service',
crossDomain:true, // Here is the JSONP callback logic
success: function(data){
console.log(data); // data is what comes back from your remote file
}
});

Resources