Ajax call from Greasemonkey to a Servlet: response failure - javascript

Though I've programming experience, am completely new to GS, JS, or anything related to UI.
Scenario: Making an AJAX call from Greasemonkey script to a Servlet
Greasemonkey/JS Code:
function getResultsData(query){
alert("Getting the Data");
$.ajax(
{
cache: false,
data: {"q":query},
dataType:"text",
url: "http://myserver.com:8000/search?",
success: processData
}); //end of $.ajax }
function processData(data){
alert("Got the data");
var myResultDiv = document.getElementById("searchRes");
myResultDiv.innerHTML = data; }
Servlet Code:
System.out.println("-----------This is an AJAX call------------------");
//Commented the original logic
resp.setContentType("text/plain");
resp.setCharacterEncoding("UTF-8");
resp.getWriter().write("Text from Servlet");
Problem:
GS/JS code works perfectly if the url (in $.ajax) is some other existing API. Response reflects in the UI
However, when I give my server's url, I can observe in the Firebug.Console that there's no http response for that call but the status says 200 OK with the whole entry turned 'RED'.
When I test the url copied from Firebug's 'http call entry', it's working perfectly as I can see the response 'Text from Servlet' on the new tab.
Can someone please help.
NOTE Website on which greasemonkey runs, and my server belong to same domain, i.e.
Greasemonkey website: wwww.example.com
My server: www.myserver.example.com

Thanks to #mattedgod. His comment triggered me to research more and I found the answer.
Add the following snippet to make it work.
response.setHeader("Access-Control-Allow-Origin", "*");
Surprisingly, it doesn't work if I explicitly specify my own server's full http address in the header. I yet to find out why.

Related

How I get respone text in application and bind to the label in cross ajax call

I am calling the web service from other domain using Ajax call and I want to get returned response from server in my application by using following code I get response text in firebug but not in my JavaScript code. Control are not showing success and error response it goes out directly.
I want response in my success or error section but both not handling in this.
I am trying lot but not finding any solution please any one help me.
I am in a trouble. I hope somebody can help me for calling cross domain web service by using Ajax call. I am trying from 1 week but didn't find any solution till. I am getting response on browser but not getting it on my actual code.
My JavaScript code.
crossdomain.async_load_javascript(jquery_path, function () {
$(function () {
crossdomain.ajax({
type: "GET",
url: "http://192.168.15.188/Service/Service.svc/GetMachineInfo?serialNumber="+123,
success: function (txt) {
$('#responseget').html(txt);
alert("hii get");
}
});
crossdomain.ajax({
type: "POST",
url: "http://192.168.15.188/Server/Service.svc/GetEvents/",
// data: "origin=" + escape(origin),
success: function (txt) {
$('#responsepost').html(txt);
alert("hii post");
}
});
});
});
</script>
You can't simply ignore the Same Origin Policy.
There are only three solutions to fetch an answer from a web-service coming from another domain :
do it server-side (on your server)
let the browser think it comes from the same domain by using a proxy on your server
change the web service server, by making it JSONP or (much cleaner today) by adding CORS headers

Call similar to $.get in $.ajax

I have the following code:
$.get(url, {}, checkResponse)
And the following function:
function checkResponse(content) {}
The parameter "content" here is the result of the "get". I wanted to implement $.ajax to able to wait for the process to complete before it jump to the next chunk of code. I tried the following code but it didn't work.
$.ajax({
async: false,
type: 'GET',
url: url,
success: function (data) {
alert(data.toString());
checkResponse(data);
},
error: function (data) {
alert("error");
}
});
Here's what happened, the alert for the data.toString() gives empty string value while it should give me the url page content, and after it hits the alert it jumps to the error section and displays the alert "error".
According to the discussion in the comments section you are trying to send cross domain AJAX calls to arbitrary urls on the internet. Due to the same origin policy restriction that's built into the browsers this is not possible.
Possible workarounds involve using JSONP or CORS but since you will be sending requests to arbitrary urls that you have no control over they might not be an option. The only viable solution in this case is for you to write a server side script that you will host on your domain acting as a bridge. This script will receive an url as parameter and send an HTTP request to this url in order to retrieve the result. Then it will simply return the result back to the response. Finally you will send an AJAX request to your own server side script.

AD FS 2.0 Authentication and AJAX

I have a web site that is trying to call an MVC controller action on another web site. These sites are both setup as relying party trusts in AD FS 2.0. Everything authenticates and works fine when opening pages in the browser window between the two sites. However, when trying to call a controller action from JavaScript using the jQuery AJAX method it always fails. Here is a code snippet of what I'm trying to do...
$.ajax({
url: "relyingPartySite/Controller/Action",
data: { foobar },
dataType: "json",
type: "POST",
async: false,
cache: false,
success: function (data) {
// do something here
},
error: function (data, status) {
alert(status);
}
});
The issue is that AD FS uses JavaScript to post a hidden html form to the relying party.
When tracing with Fiddler I can see it get to the AD FS site and return this html form which should post and redirect to the controller action authenticated. The problem is this form is coming back as the result of the ajax request and obviously going to fail with a parser error since the ajax request expects json from the controller action. It seems like this would be a common scenario, so what is the proper way to communicate with AD FS from AJAX and handle this redirection?
You have two options.
More info here.
The first is to share a session cookie between an entry application (one that is HTML based) and your API solutions. You configure both applications to use the same WIF cookie. This only works if both applications are on the same root domain.
See the above post or this stackoverflow question.
The other option is to disable the passiveRedirect for AJAX requests (as Gutek's answer). This will return a http status code of 401 which you can handle in Javascript.
When you detect the 401, you load a dummy page (or a "Authenticating" dialog which could double as a login dialog if credentials need to be given again) in an iFrame. When the iFrame has completed you then attempt the call again. This time the session cookie will be present on the call and it should succeed.
//Requires Jquery 1.9+
var webAPIHtmlPage = "http://webapi.somedomain/preauth.html"
function authenticate() {
return $.Deferred(function (d) {
//Potentially could make this into a little popup layer
//that shows we are authenticating, and allows for re-authentication if needed
var iFrame = $("<iframe></iframe>");
iFrame.hide();
iFrame.appendTo("body");
iFrame.attr('src', webAPIHtmlPage);
iFrame.load(function () {
iFrame.remove();
d.resolve();
});
});
};
function makeCall() {
return $.getJSON(uri)
.then(function(data) {
return $.Deferred(function(d) { d.resolve(data); });
},
function(error) {
if (error.status == 401) {
//Authenticating,
//TODO:should add a check to prevnet infinite loop
return authenticate().then(function() {
//Making the call again
return makeCall();
});
} else {
return $.Deferred(function(d) {
d.reject(error);
});
}
});
}
If you do not want to receive HTML with the link you can handle AuthorizationFailed on WSFederationAuthenticationModule and set RedirectToIdentityProvider to false on Ajax calls only.
for example:
FederatedAuthentication.WSFederationAuthenticationModule.AuthorizationFailed += (sender, e) =>
{
if (Context.Request.RequestContext.HttpContext.Request.IsAjaxRequest())
{
e.RedirectToIdentityProvider = false;
}
};
This with Authorize attribute will return you status code 401 and if you want to have something different, then you can implement own Authorize attribute and write special code on Ajax Request.
In the project which I currently work with, we had the same issue with SAML token expiration on the clientside and causing issues with ajax calls. In our particular case we needed all requests to be enqueud after the first 401 is encountered and after successful authentication all of them could be resent. The authentication uses the iframe solution suggested by Adam Mills, but also goes a little further in case user credentials need to be entered, which is done by displaying a dialog informing the user to login on an external view (since ADFS does not allow displaying login page in an iframe atleast not default configuration) during which waiting request are waiting to be finished but the user needs to login on from an external page. The waiting requests can also be rejected if user chooses to Cancel and in those cases jquery error will be called for each request.
Here's a link to a gist with the example code:
https://gist.github.com/kavhad/bb0d8e4a446496a6c05a
Note my code is based on usage of jquery for handling all ajax request. If your ajax request are being handled by vanilla javascript, other libraries or frameworks then you can perhaps find some inspiration in this example. The usage of jquery ui is only because of the dialog and stands for a small portion of the code which could easly be swapped out.
Update
Sorry I changed my github account name and that's why link did not work. It should work now.
First of all you say you are trying to make an ajax call to another website, does your call conforms to same origin policy of web browsers? If it does then you are expecting html as a response from your server, changedatatype of the ajax call to dataType: "html", then insert the form into your DOM.
Perhaps the 2 first posts of this serie will help you. They consider ADFS and AJAX requests
What I think I would try to do is to see why the authentication cookies are not transmitted through ajax, and find a mean to send them with my request. Or wrap the ajax call in a function that pre authenticate by retrieving the html form, appending it hidden to the DOM, submitting it (it will hopefully set the good cookies) then send the appropriate request you wanted to send originally
You can do only this type of datatype
"xml": Treat the response as an XML document that can be processed via jQuery.
"html": Treat the response as HTML (plain text); included script tags are evaluated.
"script": Evaluates the response as JavaScript and evaluates it.
"json": Evaluates the response as JSON and sends a JavaScript Object to the success callback.
If you can see in your fiddler that is returning only html then change your data type to html or if that only a script code then you can use script.
You should create a file anyname like json.php and then put the connection to the relayparty website this should works
$.ajax({
url: "json.php",
data: { foobar },
dataType: "json",
type: "POST",
async: false,
cache: false,
success: function (data) {
// do something here
},
error: function (data, status) {
alert(status);
}
});

jQuery Get Request on HTTP URL

i've recently tried to get some Response from an URL using jQuery. Therefore I copied a get request sample of jQuery API Get Request Tutorial into my project and tried to run it, but my debugging messages showed me, that it can't go further. I tried the javascript Ajax Library using a simple request, but it didn't work.
So i'm asking you, if you could help me somehow.
And this is all what i do, but there is no response.
var url = "http://www.google.com";
$.get(url, function(data){
alert("Data Loaded: " + data);
});
Did i probably forgot to include a ajax or jQuery library. For a better understanding, i have c and obj-c experince, this is why i think, that a library is missing.
In each sample there is just a short url like "test.php". Is my complete HTTP url wrong?
Thanks for your answers in advanced.
Br
Nic
I have provided an example scenario to help get you started:
<!-- Include this jQuery library in your HTML somewhere: -->
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script
This is probably best to include inside of an external JS file:
//Listen when a button, with a class of "myButton", is clicked
//You can use any jQuery/JavaScript event that you'd like to trigger the call
$('.myButton').click(function() {
//Send the AJAX call to the server
$.ajax({
//The URL to process the request
'url' : 'page.php',
//The type of request, also known as the "method" in HTML forms
//Can be 'GET' or 'POST'
'type' : 'GET',
//Any post-data/get-data parameters
//This is optional
'data' : {
'paramater1' : 'value',
'parameter2' : 'another value'
},
//The response from the server
'success' : function(data) {
//You can use any jQuery/JavaScript here!!!
if (data == "success") {
alert('request sent!');
}
}
});
});
You're hitting the Same Origin Policy with regard to ajax requests.
In a nutshell, JS/Ajax is by default only allowed to fire requests on the same domain as where the HTML page is been served from. If you intend to fire requests on other domains, it has to support JSONP and/or to set the Access-Control headers in order to get it to work. If that is not an option, then you have to create some proxy on the server side and use it instead (be careful since you can be banned for leeching too much from other sites using a robot).
As others have said you can't access files on another server. There is a hack tho. If you are using a server side language (as i assume you are) you can simply do something like:
http://myserver.com/google.php:
<?php
echo get_file_contents('http://www.google.com');
?>
http://myserver.com/myscript.js
$.get('google.php',function(data){ console.log(data) });
That should work!
you just can access pages from your domain/server

ClientLogin from Google API doesn't works with AJAX

I'm trying to login to a Google Account for request Picassa Web photos with AJAX. That's the code:
xmlhttp=new XMLHttpRequest();
xmlhttp.open("POST","https://www.google.com/accounts/Login",true);
xmlhttp.send("accountType=HOSTED_OR_GOOGLE&Email=...&Passwd=...&service=lh2&source=prova");
document.getElementById('prova').innerHTML=xmlhttp.responseText;
With this firebug shows a 200 OK status in the Net tab but an unexplained error in the Console. Of course nothing appears in the div called "prova" since answer is empty.
I also try to add this header:
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
But then firebug shows a 400 Bad Request in the Net tab. Can you help me? Thank you.
You should be able to view the ajax reponse in firebug and see what is gtting posted back to you - you can get a 200 error but still get an error in the post back. Don't you need to do something with an AuthToken too?
Solved! Firefox and new browsers don't let make AJAX call to third-party applications for security reasons. All is explained here: http://www.xml.com/pub/a/2005/11/09/fixing-ajax-xmlhttprequest-considered-harmful.html
Wasn't sure if we got the authToken or not...
Here's how I've been making xDomain Posts:
It requires having a little library (tiny) called flyJSONP, which uses YQL (Yahoo! Query Language) as a JSONP hack. Works great, but cannot post/get headers. After, I send data to php which then makes a cross-domain post with necessary header.
FlyJSONP also works with get... FlyJSONP.get({...
FlyJSONP.post({
url: "https://www.google.com/accounts/ClientLogin",
parameters: {
name: "value"
},
success: function(data) {
console.log("the response is: " + data);
},
error: function(errorMsg) {
console.log(errorMsg);
},
complete: function(data){
console.log("...completed post!");
}
});

Categories

Resources