I am using the following code to do the cross domain AJAX request with YQL :
function requestCrossDomain( site, callback ) {
function cbFunc(data) {
// If we have something to work with...
alert("inside call back");
if ( data.results[0] ) {
// Strip out all script tags, for security reasons.
// BE VERY CAREFUL. This helps, but we should do more.
data = data.results[0].replace(/<script[^>]*>[\s\S]*?<\/script>/gi, '');
// If the user passed a callback, and it
// is a function, call it, and send through the data var.
if ( typeof callback === 'function') {
callback(data);
}
}
// Else, Maybe we requested a site that doesn't exist, and nothing returned.
else throw new Error('Nothing returned from getJSON.');
}
// If no url was passed, exit.
if ( !site ) {
alert('No site was passed.');
return false;
}
// Take the provided url, and add it to a YQL query. Make sure you encode it!
var yql = 'http://query.yahooapis.com/v1/public/yql?q=' + encodeURIComponent('select * from html where url="' + site + '"') + '&format=xml&callback=cbFunc';
// Request that YSQL string, and run a callback function.
// Pass a defined function to prevent cache-busting.
$.getJSON( yql, cbFunc );
console.log("outside call back");
}
and calling the above as follow :
requestCrossDomain('http://www.cnn.com', function(results) {
alert(results);
});
When i am running the above code in firefox, although response (in firebug console) is showing the content of website inside callback function (cbFunc) yet it is showing nothing as alert.Also the result of console.log("inside call back") at line 5 is not printing in firebug console.
can anyone suggest me where things are going wrong or any explanation for above ?
btw i have already gone through :
http://tek-insight.blogspot.in/2010/05/cross-domain-ajax-request-proxy-json.html
http://net.tutsplus.com/tutorials/javascript-ajax/quick-tip-cross-domain-ajax-request-with-yql-and-jquery/
Possible explanation in related stackoverflow questions.
$.getJSON accepts as callback function for 'success' response. But if error were returned (404, 500, etc) then it will not call this function.
You need to add extra functions in order to catch other scenarios of responses:
$.getJSON( yql, cbFunc)
.done(function() { console.log( "second success" ); })
.fail(function(jqxhr, textStatus, error) { console.log( "error", textStatus, error ); })
.always(function() { console.log( "complete" ); });
Related
If the user doesn't input a correct string it will fail the try. it's fine
My only problem is that I want to send the exception to the error function in the ajax. ATM is sending it to the success.
How do I trigger some sort of error so it sends to the error function in ajax?
public static String call(String input) {
try {
//doesn't matter. it will fail this try
}
} catch (Exception e) {
return e.getMessage(); // I want to send this to the error function in ajax
}
return "Good job";
}
AJAX
$.ajax({
url: '/call',
type: 'get',
data: {input: input},
success: function (resultString) {
//it sends to here instead of error
},
error: function () {
// i want to see it here
}
})
This question is use case dependent, as the correct answer depends on the type of error, business rules and other factors like information exposure.. but to try sending you in the correct direction, you will need to send an HTTP error code, probably a 400 as in https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400
This is an example of a how a servlet can do it (this is also case dependent as the method to use depends on you back end tech):
catch ( MalformedFileUriException e ) {
response.setStatus( HttpServletResponse.SC_BAD_REQUEST );
log.warn( "...", e );
}
catch ( UnsupportedLocaleException e ) {
response.setStatus( HttpServletResponse.SC_BAD_REQUEST );
log.warn( "...", e );
}
catch ( Exception e ) {
response.setStatus( HttpServletResponse.SC_INTERNAL_SERVER_ERROR );
log.error( "...", e );
}
public static String call(String input) {
try {
//doesn't matter. it will fail this try
}
} catch (Exception e) {
echo json_encode(array("status"=>false,"msg"=>e.getMessage())); // I want to send this to the error function in ajax
}
echo json_encode(array("status"=>true,"msg"=>"Good job"));
}
JS
$.ajax({
url: '/call',
type: 'get',
data: {input: input},
success: function (resultString) {
var d = $.parseJSON(resultString);
if(d.status){
//do stuff
}else{
alert(d.msg);//Your alert message
}
}
})
AJAX doesn't catch the error thrown by server in error function. You need to do it manually to let AJAX know if it was a success or an error. You need to use json_encode and set status true or false.
Check in your AJAX if status is false it means the error was thrown from the server.
PS - I don't know the json_encode syntax in JAVA so I have used the syntax of PHP. Please replace it. But you will get the idea from this.
The ajax success or error gets executed when the AJAX call completes successfully or fails respectively. So basically it does not care what result you are returning from backend. if your backend fails to return any data, only then the AJAX will run into an ERROR block. so if you want to distinguish between your try block returning data and error block returning data you have to apply some logic in your success part of AJAX.
So my approach would be to send the data as a list of text and value rather than a string. you can set the [text] part as "OK" when your backend return data from a try block or else you can set the [text] block as "Error" in case of catch block returning. And the [Value] of list would be the desired values.
So conclusion use list<> in place of string as a return type, and set the [Text] and [Value] field as required.
I was running some jQuery code when suddenly I saw through Firebug Console that when I force a 500 error, the code inside .fail() method, is not being fired:
$.ajax({
url: "someAction.do",
data: "param1=param¶m2=param",
dataType: "xml"
}).done(function(xml){
//some stuff with my data
}).fail(function(xml){
//some other different stuff with my data that is not being fired
});
In the other hand, in a Java Action, I set the HttpResponse Status to "500" when an error occurs, for example, POSTING an invalid field trough the Ajax call, like searching in a database for an email that is not present, and then show the error trough ajax:
<xml version=bla,bla...>
<item>
<name>message</name>
<value>Invalid input data</value>
</item>
</xml>.
Any ideas why? I just want to use the new methods fail() and done(). I know I could do this using the statusCode handler.
But I allways like to follow new trends if I could. At least I would like to try that.
Thank you very much!
An alternative approach , substitute direct call to .done() or .fail() by filtering responses through .always() initially , then calling .done() or .fail() through filtering deferred ; maintaining ability to process actual net errors with same fail() callback
// simulate server-side responses
var error = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<item>"
+ "<name>message</name>"
+ "<value>Invalid input data</value>"
+ "</item>";
var success = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<item>"
+ "<name>message</name>"
+ "<value>Success</value>" + "</item>";
// params
$.ajaxSetup({
beforeSend : function(jqxhr, settings) {
var d = decodeURIComponent(settings.data)
.match(/data=+.*/)[0]
.split(/=|&/);
var params = {};
params[d[0]] = {};
params[d[0]][d[1]] = d[2];
params[d[0]][d[3]] = d[4];
jqxhr.data = params;
}
});
var request = function (url, _xmlResponse, data1, data2) {
var _response = new $.Deferred(),
_request = $.ajax({
url: url,
type: "POST",
data: {
// responses
xml: _xmlResponse,
// params
data: "param1="+ data1 +"¶m2="+ data2
},
dataType: "xml"
});
// check `responseText` for "Invalid" ,
// check `textStatus` for actual net error , "error"
_request.always(function (xml, textStatus, jqxhr) {
console.log(xml, textStatus, jqxhr, "check");
// simulate server-side processing, cont.
// if both object passed to server ,
// `param1` and `param2` _do not_ have property
// with value of at `params` , `""` empty string - generic "error" ,
// _and_ returned `responseText` contain "Invalid" ,
// _or_ `textStatus` : `error` , `reject` `dfd` , call `.fail()`
// else `resolve `dfd` , call `.done()`
// check params
var test = [xml["data"] || jqxhr["data"]].every(function(v, k) {
return !(v.data["param1"] !== "" && v.data["param2"] !== "" )
}) ;
// check `xml` responseText for node for "Invalid" text ,
// generate `.fail()`
var check = $(xml.children)
.find("value").is(":contains(Invalid)");
return check && test || textStatus === "error"
// call `.fail()`
? _response.reject([xml, textStatus, jqxhr])
// call `.done()`
: _response.resolve([xml, textStatus, jqxhr])
});
return _response
.done(function (xml) {
// do `done()` stuff
console.log(xml[0], xml[1], xml[2]);
var msg = $(xml[0].children).find("value").html();
$("#success")
.html(msg + ", "
+ xml[2].data.data.param1
+ xml[2].data.data.param2
);
return this.promise()
})
.fail(function (xml) {
// do `.fail()` stuff
console.log(xml[0], xml[1], xml[2], "fail");
var msg = $(xml[0].children).find("value").html()
|| xml[1] + ", " + xml[2];
$("#error")
.html(msg);
return this.promise()
});
};
Could then call request() , without _xmlResponse param , which should handle both generated .fail() (if responseText contains "Invalid") and net error .fail() calls (e.g., statusCode 500; textStatus error) , and .done() calls .
request("someAction.do", "param1_param", "param2_param");
Optionally, chain returned promise from request at .always() , as data array containing request return values ; after being processed at .done() or fail()
request("someAction.do", "param1_param", "param2_param")
.always(function(data) {
// do `.done()` , `.fail()` stuff ,
// `data, textStatus, jqxhr`
console.log(data[0], data[1], data[2])
})
jsfiddle http://jsfiddle.net/guest271314/ek15krb5/
I think that depends on the parameter "xml", if:
1. xml is a real xml object ,it'll trigger 'done';
2. xml is not a xml object ,it'll trigger 'fail'
Even if you return a 500 error code ,it is still a valid xml object, So it'll trigger "done"
I'm dealing with this piece of code and I'm going crazy since I can not find where my error is:
$.post($form.attr('action'), $form.serialize(), function (result) {
console.log(result);
if (result.success === false) {
console.log("no success");
} else {
console.log("success");
}
}, 'json')
This what console.log(result) outputs: Object {success: true, errors: "", redirect_to: "/app_dev.php/login"} but the conditional is not going through no success either success, why? Where I'm making the mistake?
From jQuery.post() | jQuery API Documentation:
success
Type: Function( Object data, String textStatus, jqXHR jqXHR )
A callback function that is executed if the request succeeds. Required
if dataType is provided, but can be null in that case.
Try adjusting your callback function definition from function (result) { to:
function( data, result ){
Then use the result string to run your conditional.
Without seeing more of what's going on behind the scenes with your $form object, I'd guess that something else there may be interrupting execution. Try NOT running the console.log() until after your conditional.
I am sending the jsonp request as:
var jsoncallback = "?jsoncallback=?"
$.getJSON( reportURL + jsoncallback, {
tags: "",
tagmode: "any",
format: "json"
})
.done(function( data ) {
$.each( data.items, function( i, item ) {
alert( item );
});
});
I have put an alert to see if the request works. On server side, in node js file I am responding to request as:
..
console.log("request received");
response.writeHead( 200, { "Content-Type": "application/json" } );
..
response.end();
In the logs I can see that the request received. The problem is that no alert windows pops up.
What could be the reason to this?
I just reponse.writeHead(...) and (for testing reasons - just the head and end) response.end()
With the jsoncallback=? in the URL, jQuery is expecting a JSONP <script> as a response. For this to work, the server should at the very least write out the "padding."
That is a call to the function named by jsoncallback. And it won't be just ? -- jQuery replaces that with a pseudo-random function name along the lines of jQuery1910123456789_0123456789. For that, the response should at least be:
jQuery1910123456789_0123456789();
You'll need to get the value from the request.url:
var parsedUrl = url.parse(request.url, true);
var query = parsedUrl.query || {};
if ('jsoncallback' in query) {
response.write(query.jsoncallback + '();');
}
// ...
And, once you have data to output with it:
if ('jsoncallback' in query) {
response.write(query.jsoncallback + '(' + JSON.stringify(data) + ');');
} else {
response.write(JSON.stringify(data));
}
Have you confirmed the JSON is correctly formatted? Check it against http://jsonlint.com/.
From the getJSON() docs:
As of jQuery 1.4, if the JSON file contains a syntax error, the
request will usually fail silently.
I have an ajax request in my javascript that is sending data to a Rails controller. If the controller finds that the data is duplicate of information already in the database, it returns an 'Unprocessable Entity' error.
I would like to have a dialog open and ask a user if he is sure he wants to insert the duplicate information. If the user says yes, I'd like to add another key to the data object and retry the request. The key added would be a flag that ignores the duplicate check and inserts the data anyway.
$.ajax({
url: '/url',
type: 'post',
data: this.buildData(),
success: function() {
bootbox.alert('Information added', function() {
Backbone.history.loadUrl();
}.bind(this)
);
}.bind(this),
error: function(jqXHR, textStatus, errorThrown) {
if(errorThrown === 'Unprocessable Entity') {
bootbox.confirm('Do it anyway?', function(confirm) {
if(confirm) {
/*Here I want to add another key to the data object and resend the request*/
}
}.bind(this)
);
}
}.bind(this)
});
How would I go about doing this, or better yet, is there a better way of doing what I am trying to accomplish?
First of all I am sure there is some plugin for that.
But if no plugin is suitable you can always do something like this
function dispatchAjax( options ){
options = $.extend({},options);
var data = $.extend({}, this.buildData(), options.data );
$.ajax({ ... ,
error : function( ) { ....
if ( typeof(options.retry) == "function" ){
var retryFunc = options.retry;
options.retry = null;
options.data = { "extraKey":"extraValue"};
dispatchAjax( options );
}
});
}
give me some time to make sure this runs properly and give full code
Another way you might be interested is using synchronous call. {"async":false} in JQuery's ajax request.
I know this might seem to defeat the purpose, however I found it quite useful for server side validation - so it might suite your needs and you won't have to deal with complicated handlers as I show above, it would simply be something like this :
var result = dipatchRequest( options, /*async*/ false, /*ignore-duplicates*/ false );
if ( result.error && confirm(..) ){
dispatchRequest(options, true, true);
}