I have a function that makes an Ajax request for any anchor. The request method can be GET or POST. In this case, I want to make a POST without using a form but the Ajax request throws an error before even sending the request. The error has the value "error" and all error/failure description variables are "".
function loadPage(url,elem_id,method,data) {
ajaxLoading(elem_id);
$.ajax({
type: method,
url: url,
data: data,
success:function(data){
$("#"+elem_id).html(data);;
},
error:function(request,textStatus,error){
alert(error);
}
});
}
When the function is called the params are these (copied from the js console):
data: "partial=yes"
elem_id: "page"
method: "post"
url: "/projects/2/follow"
As asked, here is the code that calls the loadPage function.
$("body").on("click","a.ajax",function(event) {
var _elem = getDataElem($(this));
var _method = getRequestMethod($(this));
var _partial = getRequestPartial($(this));
handlers.do_request(event,$(this).attr("href"),_elem, _method, _partial);
});
var handlers = (function() {
var obj = {};
obj.do_request = function(event,url,elem_id,method,data) {
event.preventDefault();
loadPage(url,elem_id,method,data);
history.pushState({selector:elem_id,method:method,data:data},null,url);
};
}());
After the failure of the Ajax request, the request is made by default and it responds sucesss. In all I have read, this seems to be a valid way to make a POST request (that doesn't need a form).
Am I doing something wrong in the function? Why is the error information empty?
Thanks
EDIT:
I have been thinking, for a POST from a "form" that function works, when the variable "data" is made with the serialize function (e.g. "var data = $(this).serialize();"). Could it be that the format of the "data" when I make a POST without a "form" is wrong in someway? Maybe the JQuery Ajax function doesn't accept a simple string like "partial=yes" as data when a POST is made. Any thoughts on this?
I just experienced this problem and after an hour or two, thought to try setting cache to false. That fixed it for me.
$.ajax({
url: url,
cache: false,
type: method
});
Unfortunately, when I removed cache again, my request was working as if it had never had a problem. It seems as if setting cache:false made something 'click'.
Oh well.
Just a guess, but in the docs the type parameter is in all caps, i.e. 'POST' and not 'post'.
Try:
function loadPage(url,elem_id,method,dat) {
ajaxLoading(elem_id);
$.ajax({
type: method,
url: url,
data: dat,
success:function(data){
$("#"+elem_id).html(data);;
},
error:function(request,textStatus,error){
alert(error);
}
});
}
I'm wondering if you are running into a problem using a variable named after a keyword. If this doesn't work, try calling loadPage with no arguments and hard coding all of your ajax parameters, just to see if that works.
Could not solve the problem, neither could find the reason why it was happening. Although, I found a way around, by using a hidden empty form instead of an anchor with the method 'POST'. For a form, the function worked nicely.
Thanks for the answers
Related
I was using antiforgerytoken within my razor view, and it was working fine. Then I moved the same code to AJAX, and it has started giving weird problems.
The AJAX POST request works fine, but the action SendData() which is called from the AJAX has a redirect to a different View (return View("Close");), which does not work anymore. It worked perfectly fine when the SendData() was called from the form directly.
Working code:
#using(Html.BeginForm("SendData", "Controller", FormMethod.Post)) {
#Html.AntiForgeryToken():
}
Not working code:
#using(Html.BeginForm("", "", FormMethod.Post, new
{
id = "__AjaxAntiForgeryForm"
}))
{
#Html.AntiForgeryToken()
}
JS File:
var form = $('#__AjaxAntiForgeryForm');
var token = $('input[name="__RequestVerificationToken"]', form).val();
$.ajax({
type: 'POST',
url: '/Controller/SendData',
data: {
__RequestVerificationToken: token
},
cache: false,
success: function(result) {}
});
The Action SendData() executes fine, but the redirect within this action doesn't work anymore.
I advise you use .serialize() instead of the following line.
var token = $('input[name="__RequestVerificationToken"]', form).val();
It is generic and thus will automatically adapt to any model changes.
For a working example of Antiforgery used alongside Ajax check this answer. The question was asked for MVC3 but it should work perfectly well as long as you're using an MVC version above 3.
The result param in the success: function (result) part of the ajax call will receive whatever was returned by your SendData action. If the SendData action uses a return View([...]); then you will probably get some html code in your result var. You could also return json data as follow return Json([...]).
If you actually want to have a redirect be made by the result of your Ajax call you should return the URL that you want to use as the redirection's target as follow return Content("http://target.url.for.redirect.com"); and then in your success callback, using the location.replace method, do this:
success: function(result)
{
document.location.replace(result);
}
This way the URL returned by the Ajax controller will be used to execute a redirection.
NOTE if you wish to ALWAYS redirect the user after the form is sent you should not use ajax at all ! A regular POST form would be far better suited for the job.
I figured out the problem, as per the comment from Stephen Muecke. The AJAX calls don't allow redirects, as the whole point behind AJAX is to stay on the same page and make a background JS call.
I'm using the jQuery Post function, for example:
var fooVar = true;
var barVar = 1;
var bazVar = "baz";
$.post("url",
{
foo: fooVar,
bar: barVar,
baz: bazVar
},
function(){
alert("success");
}
);
In my logs, I'm seeing an intermittent issue where requests to "url" are being made without any form parameters, and I only have this one function which calls it.
Is there ever a situation in which the POST request can be fired, without sending the form parameters specified in jQuery Post?
I would expect to see:
foo=true&bar=1&baz=baz
However there are no form parameters at all:
UPDATE: This issue seems to be mainly on Internet Explorer browsers (IE7-IE11) from looking at the stats, however its not exclusive to IE (Chrome, Firefox have also had issues).
jQuery Post can send a request without form parameters when the parameter values are undefined.
For example if we have the following:
var fooVar = undefined;
var barVar = 1;
var bazVar = "baz";
$.post("url",
{
foo: fooVar,
bar: barVar,
baz: bazVar
},
function(){
alert("success");
}
);
Then the form parameters posted will be:
bar=1&baz=baz
Now this doesn't solve my actual issue (from what I can tell correct conditions have been put in place to only make the call if all variables have a value), but it does answer my question.
Sounds like a browser version specific issue, try to reproduce it locally with different versions of IE. It might be a typo in the code that is handled gracefully by some versions of IE but not the others (like the trailing comma in arrays) - run a JSLint/JSHint on your JavaScript code. Another scenario I can think of is CORS preflight OPTIONS request - that has no body. Are you sure that you are not executing a CORS request? Does your Ajax URL match the origin?
Instead of using the $.post shorthand, try using $.ajax instead; not sure whether that will solve it, but it certainly won't hurt to try it out.
Plus, you'll have one less function call to worry about. Micro-optimisations ftw!
$.ajax({
type: "POST",
url: "url",
data: { foo: bar }
});
$.post is a shorthand way of using $.ajax for POST requests, so there isn't a great deal of difference between using the two . maybe the problem is somewhere else in your code, not in jquery or you browser.
but try $.ajax. it is generally better to use if you require a greater depth of configuration over your ajax request. it should work
e.g.
$.ajax({
type: "POST",
url: "test_url",
data: { name: "John", location: "Boston" },
success: function(response) {
alert('success !');
}
});
here is more https://api.jquery.com/jQuery.ajax/
Why is name undefined?
$('#langs li').click(function(){
var name = $(this).attr('value');
$.ajax({
type: "POST",
url:'test.php',
data: 'name='+name,
success:function(raspuns){
//$('#content1').html(raspuns);
var ras = raspuns;
$.ajax({
type: "POST",
url: "index.php",
data: 'ras='+ras;
)};
}
});
});
You can check a few things:
make sure you have data before sending. you have value attribute on li? or if you want to get li contents, use html() or txt(). But probably you want to get input field value inside li?. then use $(this).find("input").val() if you have just one input inside.
Then others to check:
1) Visit http://example.com/test.php to make sure it echoes the response correctly. You may have error in php or the link may not be accessible.
2) Your url is like this: http://example.com/test.php ? It is also fine if you have a virtual host in your local machine like http://example.local/test.php. But it will not work if you have something like
http://localhost/mysite/test.php
unless you correct your path in ajax call to a full link.
3) Make sure your javascript doesnt fail before sending. I mean, are you able to do alert(name) ? You can also use beforeSend() above success to check if you are ending data correctly.
4) Make sure you are not trying to make a cross domain ajax request as you can't do so with POST.
5) May try using "/test.php" instead of "test.php" although it wouldn't be the problem, I think.
You can also use console to see what is going on.
If what you mean is that raspuns seems to be undefined, maybe it's because you did not echo your response from test.php?
test.php
...
echo 'this is my response';
AJAX call
$.ajax({
...
success: function(raspuns) {
// raspuns == 'this is my response'
}
});
And also, if you're passing POST data, I think it would be better if you pass a JSON object, like so:
$.ajax({
url: 'test.php',
type: 'POST',
data: {name: name},
...
});
li elements don't support a value attribute. Perhaps you're looking for an input or the contents of li via .html().
See in this demo that name is undefined: http://jsbin.com/IzOXiJOZ/2/edit
My question regards the $.ajax() jQuery method. I can't get the success parameter in $.ajax() to work.
This works:
$.ajax({
type: 'POST',
url: "/getCodes.php?codes=billingCodes&parent="+$('#wClient').val(),
dataType: 'json',
success: window.alert("inside aJax statement")
});
This does not:
$.ajax({
type: 'POST',
url: "/getCodes.php?codes=billingCodes&parent="+$('#wClient').val(),
dataType: 'json',
success: function(){
window.alert("inside aJax statement");
}
});
In the first case, I get a JavaScript alert window that lets me know the $.ajax() I called is working. All that is changed in the second block of code is I put the window.alert() inside a function() { window.alert(); }.
The point of this is to verify that the $.ajax is running so I can put some actual useful code in the function(){} when the $.ajax runs successfully.
In your second example nothing will happen unless you get a successful call back from the server. Add an error callback as many here have suggested to see that indeed the ajax request is working but the server is not currently sending a valid response.
$.ajax({
type: "POST",
url: "/getCodes.php?codes=billingCodes&parent="+$('#wClient').val(),
dataType:"json",
success: function(response){
alert(response);
},
error: function(jqXHR, textStatus, errorThrown){
alert('error');
}
});
helpful Link in tracking down errors.
Your first example does nothing whatsoever to prove that the ajax call has worked. All it does is prove that the ajax function was reached, because the values of the properties in the anonymous object you're passing into the ajax function are evaluated before the function is called.
Your first example is basically the same as this:
// THIS IS NOT A CORRECTION, IT'S AN ILLUSTRATION OF WHY THE FIRST EXAMPLE
// FROM THE OP IS WRONG
var alertResult = window.alert("inside aJax statement");
$.ajax({
type: 'POST',
url: "/getCodes.php?codes=billingCodes&parent=" + $('#wClient').val(),
dataType: 'json',
success: alertResult
})
E.g., first the alert is called and displayed, then the ajax call occurs with success referencing the return value from alert (which is probably undefined).
Your second example is correct. If you're not seeing the alert in your second example, it means that the ajax call is not completing successfully. Add an error callback to see why.
In first case window.alert is executed immidiatly when you run $.ajax
In second it run only when you receive answer from server, so I suspect that something wrong in you ajax request
You may want to try and use a promise:
var promise = $.ajax({
type: 'POST',
url: "/getCodes.php?codes=billingCodes&parent="+$('#wClient').val(),
dataType: 'json'
});
promise.fail( function() {
window.alert("Fail!");
});
promise.done( function() {
window.alert("Success!");
});
What this does is saves the ajax call to a variable, and then assigns additional functionality for each of the return states. Make sure that the data type you are returning is actually json, though, or you may see strange behavior!
Note that js is single-threaded; the reason your first example works is because it actually executes the code next 'success' and stores the result. In this case there is nothing to store; it just pops an alert window. That means that the ajax call is leaving the client after the alert is fired: use the developer tools on Chrome or equivalent to see this.
By putting a function there, you assign it to do something when the ajax call returns much later in the thread (or, more precisely, in a new thread started when the response comes back).
I think that you do it right, but your request does not succeeds. Try add also error handler:
error: function(){alert("Error");};
I guess that dataType does not match or something like that.
It is 100% your second example is correct. Why it does nothing? Maybe because there is no success in the ajax call.
Add "error" handler and check waht does your ajax call return with the browsers' developer tool -> Network -> XHR . This really helps in handling of broken / incorrect ajax requests
I am using jsonp and ajax to query a web-service written in java on another server. I am using the following jquery command:
$.ajax({
type: "GET",
url: wsUrl,
data: {},
dataType: "jsonp",
complete: sites_return,
crossDomain: true,
jsonpCallback: "sites_return"
});
function jsonp_callback(data) {
console.log(data);
}
function sites_return(data) {
console.log(data);
}
So my problem is that after the query finishes a function called jsonp_callback is called. Where I can clearly see the json formatted string:
{"listEntries":["ELEM1", "ELEM2", "ELEM3", etc...]}
But after the function sites_return is called when the complete event fires, I get the the following:
Object { readyState=4, status=200, statusText="parsererror"}
Also for reference the jsonp_callback function is called before the sites_return function. Also if i take the jsonp_callback function out of the code, I get a complaint it firebug that the function is not implemented.
My question three fold:
1) What am i doing wrong on the jquery side?
2) Why does the json get parsed correctly in jsonp_callback but not sites_return?
3) What can i do to fix these issues?
EDIT
Some new development. Per the comments here is some additional information.
The following is what comes out of the http response
jsonp_callback({"listEntries":["ELEM1", "ELEM2", "ELEM3"]})
I assume this is the reason jsonp_callback is being called. I guess my question now becomes, is there any way to control this (assuming i don't have access to the back end web-service).
Hope this helps~
var url = "http://maps.google.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&sensor=false";
var address = "1600+Amphitheatre+Parkway";
var apiKey = "+Mountain+View,+CA";
$.getJSON("http://maps.google.com/maps/geo?q="+ address+"&key="+apiKey+"&sensor=false&output=json&callback=?",
function(data, textStatus){
console.log(data);
});
I believe that the first argument to the sites_return function would be the jqXHR Object. Instead of complete try using success.
But still this may not work as it seems that there is a parsing error (mentioned in the return value of sites_return function called from oncomplete). Therefore, you would first need to check your json string.
To Validate JSON, you can use http://jsonlint.com/
I think that the problem is that your server is not behaving the way jQuery expects it to. The JSONP "protocol" is not very stable, but generally what's supposed to happen is that the site should look for the "callback" parameter and use that as the function name when it builds the JSONP response. It looks as if your server always uses the function name "jsonp_callback".
It might work to tell jQuery that your callback is "jsonp_callback" directly:
$.ajax({
type: "GET",
url: wsUrl,
data: {},
dataType: "jsonp",
complete: sites_return,
crossDomain: true,
jsonpCallback: "jsonp_callback"
});
Not 100% sure however.
If you don't have the ability to change the JSONP function wrapper that the remote server returns, jQuery's $.ajax() may be overkill here. Ultimately, all you're doing is injecting a script reference to wsUrl, which makes a call to jsonp_callback with a JavaScript object literal as its input parameter.
You could just as easily do something like this and avoid the confusion around the callback naming/syntax:
$.getScript(wsUrl);
function jsonp_callback(response) {
// Access the array here via response.listEntries
}