jQuery 1.5.2 displays [object XMLDocument] for empty responses - ajax

I have a Url from which I can get a string
If the response string contains something, everything goes well, but (god forbid!) if the result would be an empty string like "" jQuery 1.5.2 will display it as [object XMLDocument]
follow the codes plz :
$.post('/Applicant/RequestedJob/IsThereActivePeriod',{},
function(data){
if(data == '' )
{
//do something here!
}
else
{
console.log(data.toString());
// [object XMLDocument] will be printed in console.
}
});
Perhaps I should mention that it used to work perfectly on jQuery 1.4.4
any idea?
Regards :)

You should set the expected dataType of the response in your ajax call, like this:
$.post('/Applicant/RequestedJob/IsThereActivePeriod',{},
function(data){
if(data == '' )
openDialog('/Applicant/RequestedJob/AddRequestedJobWindow','pnlRequestedJob','Request Window');
else
{
msgbox.show(data.toString(),'Error', msgBoxButtons.okOnly);
console.log(data.toString());
}
},
'html'
);
Without this, jQuery tries to infer the response type, according to this:
Default: Intelligent Guess (xml, json,
script, or html).
With no returned content, it's apparently guessing XML. By passing it 'html' as the dataType, you force jQuery to interpret the response as HTML, and store the result in plain text.
As per some of the comments, an appropriate content-type header should allow jQuery to infer that your empty string is HTML, achieving the same result without setting the expected dataType explicitly in the ajax call.
The reason you get [object XMLDocument] is because data is an XML document object, and its toString() is being called.

Related

AJAX response returns current page

I was searching for a similar issue for a while now, but none of the solutions worked for me (and I couldn't find exactly the same issue).
First of all, the website I'm working on is running on Zend Framework. I suspect that it has something to do with the issue.
I want to make a pretty basic AJAX functionality, but for some reason my response always equals the html of the current page. I don't need any of Zend's functionality, the functions I need to implement could (and I'd prefer them to) work separately from the framework.
For testing purposes I made it as simple as I could and yet I fail to find the error. I have a page "test.php" which only has a link that triggers the ajax call. Here's how this call looks:
$('.quiz-link').click(function(e){
e.preventDefault();
$.ajax({
URL: "/quiz_api.php",
type: "POST",
cache: false,
data: {
'test': 'test'
},
success: function(resp){
console.log(resp);
},
error: function(resp){
console.log("Error: " + reps);
}
});
});
And this quiz_api.php is just:
<?php
echo "This is a test";
?>
When I click on the link I get the entire HTML of the current page. "This is a test" can't be found there. I'm also getting an error: "Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check http://xhr.spec.whatwg.org/."
I reckon it has to do with the JS files that are included into this HTML response, but I've also tried setting "async: true" and it didn't help.
I would like to avoid using Zend Framework functions for this task, because I'm not well familiar with it and even making a simple controller sounds rather painful. Instead I want to find out what's causing such behavior and see if it can be changed.
PS: I've also tried moving quiz_api.php to another domain, but it didn't change anything.
I know that it might be an older code but it works, simple and very adaptable. Here's what I came up with. Hope it works for you.
//Here is the html
Link Test
<div id="test_div"></div>
function test(){
// Create our XMLHttpRequest object
var hr = new XMLHttpRequest();
// This is the php file link
var url = "quiz_api.php";
// Attaches the variables to the url ie:var1=1&var2=2 etc...
var vars = '';
hr.open("POST", url, true);
//Set content type header information for sending url encoded variables in the request
hr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
// Access the onreadystatechange event for the XMLHttpRequest object
hr.onreadystatechange =
function(){
if(hr.readyState == 4 && hr.status == 200){
var return_data = hr.responseText;
console.log(return_data);
document.getElementById('test_div').innerHTML = return_data;
}else{
document.getElementById('test_div').innerHTML = "XMLHttpRequest failed";
}
}
//Send the data to PHP now... and wait for response to update the login_error div
hr.send(vars); // Actually execute the request
}
you can change the whole page with a document.write instead of changing individual "div"s

Ajax & Grails - how to use the params from the model in the success of the Ajax?

I have an Ajax which call to an action in a controler.
The controller render:
render template:"changePassword", model:[user: user, passwordError: passwordError]
The passwordError is boolean.
In case the passwordError is true I have to perform function in the js.file.
How can I check in the success's Ajax the value of the passwordError?
The code of the Ajax:
$.ajax({
url: changePassword,
type: "post",
data: {
password: $('#password').val(), npassword: $('#npassword').val()
},
success: function(data,textStatus){
$('#changePassSuceess').modal()
}
});
If you dont need to render a template, you can return a json as #Eylen mentioned and then access the flag from json. If you must render a template then you can have a hidden field in your template with value set to the flag passwordError and then you can get the value of flag from this hidden field in your javascript code
See this question for how to find hidden element in jquery ajax response html
If you don't need to show the template that you are returning, then you can change your return from the controller to something like the following
return [passwordChanged:true] as JSON
Ans then in your ajax call you will have access to the JSON object in the data attribute.
console.log(data.passwordChanged);
Maybe you have to tell also in the ajax call that the return type is json.

Why does my AJAX call return <\/button> instead of </button>?

my AJAX call is
function xml_getsitepage($idsite){
$.ajax({
url: 'public/xml/xml_getsitehtml.php',
dataType: 'JSON',
data: {
"id":$idsite
},
type: 'POST',
success: function (response) {
$("#nav").html(response.nav);
}
});
return;
}
The last few lines of 'public/xml/xml_getsitehtml.php' are
$arr['htmlnav']=$htmlnav;
$arr['htmlcontain']=$htmlcontain;
$arr['isOK']="Is OK";
}else{
$arr['htmlnav']='Failed1';
$arr['htmlcontain']='Failed1';
}
}else{
$arr['htmlnav']='Failed2';
$arr['htmlcontain']='Failed2';
}
echo json_encode($arr);
exit;
The firebug response tab shows all as "</button>"
where the JSON tab shows them correctly
I have search the web but cannot find anything to help me.
I cannot "see" the data in my browser and the #nav remains blank but if I manually place the html with the \ removed it displays OK.
By default, PHP's json_encode will escape / characters in strings.
This:
Does not change the data. "\/" and "/" are two different, but valid, and equal, JSON representations of a / character.
Lets you use the output as a JavaScript literal, inline in an HTML document, without </script> ending the script element in the middle of the string.
Whatever your problem is, it has nothing to do with the escaped slashes.
If it was, then your generated HTML would have some invalid end tags in it, which would be ignored or treated as text. So you would get more text content in your button then you intended.
Your problem is this mismatch:
$arr['htmlnav']=$htmlnav;
response.nav
You are writing to htmlnav but trying to read from nav.
Slashes are being escaped. Simply unescape the string once you receive it on the front-end.
Or if you're feeling lazy, you can disable the escaping function in the PHP script:
echo json_encode($arr, JSON_UNESCAPED_SLASHES);

Import a JS array using ajax to pass though to a function/plugin in JQuery

I have a generated array which if hard coded passes the array objects to a function for processing fine.
For example:
$("#termCloud").jQCloud([{text:'some',weight:10},{text:'thing',weight:8}]);
However, I need to make this more dynamic so am generating the the array externally and importing using ajax. This is what I'm Trying:
(generateArray.asp would output {text:'some',weight:10},{text:'thing',weight:8})
$.ajax({
url: '/generateArray.asp',
success: function(data){
$("#wordCloud").jQCloud([data]);
}
})
I have tried several dataTypes and all fail.
The problem seems to be that the in the working version the JQCloud plugin receives the array as objects: [object Object],[object Object] where as my ajax version receives/sends it as a string: {text:'some',weight:10},{text:'thing',weight:8}
Is there a way to import the the array and pass it though to the JQCloud function/plugin as a proper array rather than a string or convert the string to an array for processing?
Many thanks..
In repospone to two answers below; I should point out that the return doesn't seem to be recognised as valid JSON data...
I guess you should JSON-parse the data variable before sending it to the plugin:
var json = JSON.parse(data);
$("#wordCloud").jQCloud([json]);
...or you could add
dataType : 'json'
...to the settings parameter in the ajax function call.
Try:
success: function(data){
$("#wordCloud").jQCloud([{text: data[0].text, weight: data[0].weight}, {text: data[1].text, weight: data[1].weight}]);
}
The response is automatically converted to Objects by the $.Ajax() function, as it is a json-string.

What do browsers want for the Content-Type header on json ajax responses?

I am returning some json which needs to be handled by javascript as the response to an XMLHTTPRequest.
If I set the response's content type to "text/plain", all browsers but Chrome will accept it and pass it to my JS with no problem. However, Chrome will wrap the response in
<pre style="word-wrap: break-word; white-space: pre-wrap;">
before passing it to my javascript.
If I set the response's content type to the "proper" "application/json" all browsers but Firefox will accept it and pass it to my JS with no problem. Firefox, however will ask to save or open the response as a file.
What's the correct, cross-browser Content-Type?
You may solve the issue by parsing the response into the JSON object by using jQuery funcion parseJSON - http://api.jquery.com/jQuery.parseJSON/
The parameter you pass into the function is the JSON object string, which you extract from the response data:
function AjaxResponse (data) { // AJAX post callback
var jsonResult = $.parseJSON(data.substring(data.indexOf("{"), data.lastIndexOf("}") + 1));
}
Tested (besides Chrome which problem this solves) in FF and IE8 for the following simple JSON result, for other browsers and more complex responses no guarantees...
NOTE: the content type in this case is text/plain or text/html I think - I've used the following ASP.Net MVC function to return the result
ContentResult System.Web.Mvc.Controller.Content(string content);
Where I returned the JSON object like
System.Web.Script.Serialization.JavaScriptSerializer jsonSerializer
= new System.Web.Script.Serialization.JavaScriptSerializer();
var jsonResponse = jsonSerializer.Serialize(
new { IArticleMediaId = 0
, ImageUrl = Url.Content(fullImgPath)
});
return Content(jsonResponse);
In ajaxFileUpload.js in uploadCallback() replace
io.contentWindow.document.body.innerHTML.innerHTML
with
$(io.contentWindow.document.body.innerHTML).html()

Resources