jQuery.post not always sending form data - javascript

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/

Related

Undefined index on ajax call only for one function

I have several different ajax calls on the same php page, but I get undefined index for only one function (createAlbum).
I send exactly the same parameters in each of my ajax calls. It worked fine for a few tests, but now it only works for the other ones, but not for this specific call.
I suspected that the .js file was still in the browser cache, so I cleared it and tried with other browsers, which worked for a few more attempts.
Now, I can't get it working on any browser, and definitely don't understand why.
Here is my ajax call :
$.ajax({
type: "POST",
url: BASE_URL,
data: {
action: "createAlbum",
data: JSONAlbum
},
cache: false,
success: callback
});
My php file handling the request ($_POST['action'] is always undefined with the above request) :
if (isset($_POST['action'])) {
switch ($_POST['action']) {
// Handle the action
// ...
}
} else {
echo 'ACTION : '.$_POST['action'];
}
The header containing the ajax parameters ("data" is a json containing one or more blob images, this might be the problem, but I didn't find anything saying so) :
And finally, the response containing the error :
I really hope this is not a dumb error of mine, but I asked a friend before posting, and he can't find the solution either.
Thanks for your help !
You said that the error not happens all the time (in some call yes, in other no).
The body post is sent, you see it in console. So we can exclude javascript problem.
So the problem is something that happens before or during the process.
PHP has some limitations on input vars, you can see it in php.ini.
I see that you send images in base64, so it's probable that something of these limitations are triggered.
See for example:
max_input_time
max_input_vars
post_max_size

jQuery AJAX request to remote API blocked

I have been successfully accessing data from an external weather data service API for some time now using PHP cURL. Sometimes it takes a few seconds, sometimes up to 15 seconds for this web service to process my request. Therefore, I would like to perform this operation asynchronously.
I am trying jQuery AJAX to send this GET request now. However, it keeps throwing the following error:
"No Access-Control-Allow-Origin header is present on the requested resource".
I'm aware of the "same origin policy" restrictions, and have been researching it extensively here on stackoverflow and the jQuery docs. The docs say that JSONP requests are not subject to this restriction. When I try to designate JSONP as the dataType, I get an "unexpected token" syntax error.
I have the user entering in their zip code into a form text box, then click the button to submit. This sends the GET request to the web service. I'm very comfortable with PHP, but a newbie with jQuery and AJAX. I appreciate the help with this, and look forward to the day when I can help others as I've been helped here.
Here is the jQuery code:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"> </script>
<script type="text/javascript">
$(document).ready(function () {
$('#btnGetETo').click(function () {
var resultElement = $('#resultDiv');
var requestData = $('#txtZip').val();
$.ajax({
url: 'http://et.water.ca.gov/api/data?appKey=B51CF64B-C37B-406A-83F1-1DBD8CE40EEF&targets=94805&startDate=2015-07-01&endDate=2015-07-01&dataItems=day-asce-eto,day-eto,day-precip&unitOfMeasure=E;prioritizeSCS=Y',
method: 'get',
data: { q: requestData },
dataType: 'json',
success: function (response) {
if (response.message != null) {
resultElement.html(response.message);
}
else {
resultElement.html('ETo: ' + response.DayAsceEto[0].value);
}
},
error: function (err) {
alert(err);
}
});
});
});
</script>
Unfortunately, it seems that the API in question does not support JSONP. In fact, they seem to have gone out of their way to make it difficult to query via JavaScript.
Here's how to test for JSONP (not foolproof, but most mainstream JSONP-enabled services will respond correctly). Take whatever URL you were planning to send, and add &callback=foo to the end of it. (If there are no other query string parameters of course, use ? instead of &.)
If the server supports JSONP, the response should look like:
foo({
...
});
If not, it'll look like:
{
...
}
As you can see, the only difference is that JSONP-enabled servers can wrap the JSON in a function of arbitrary name. Some servers will insert a little extra code for safety/convenience. For example, the following output was generated by the JSONplaceholder API using the URL http://jsonplaceholder.typicode.com/users/1?callback=foo:
/**/ typeof foo === 'function' && foo({
"id": 1,
"name": "Leanne Graham"
...
});
The upshot of all this is that it's the API provider's fault, not yours. If I were giving them feedback I'd make the following suggestions:
Handle cross-origin requests correctly.
Allow fallback to JSONP.

JQuery Ajax POST throwing an empty error without making the request

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

Force Backbone fetch to always use POST

I have a Collection that needs to POST some data to its url to get the data it needs. The answer to these two questions, Fetch a collection using a POST request? and Overriding fetch() method in backbone model, make it seem like I should be able to get it to work like this:
fetch: function( options ) {
this.constructor.__super__.fetch.apply(this, _.extend(options,{data: {whatever: 42}, type: 'POST'}));
}
, but Firebug still shows me a 404 error that is happening because a GET is being executed against the url in question (and the underlying Rails route only allows POST). Should this be working? If so, what else might I try? If not, what have I done wrong?
After reading the question again, here's a way to force the fetch to use POST per fetch call. (Thanks for the comments)
yourCollection.fetch({
data: $.param({id: 1234}),
type: 'POST',
success: function(d){
console.log('success');
}
});
Another approach is to override the AJAX implementation itself to use POST for all calls.
Backbone.ajax = function() {
var args = Array.prototype.slice.call(arguments, 0);
_.extend(args[0], { type: 'POST' });
return Backbone.$.ajax.apply(Backbone.$, args);
};

Is there a Request.IsMvcAjaxRequest() equivalent for jQuery?

I prefer to use jQuery with my ASP.NET MVC apps than the Microsoft Ajax library. I have been adding a parameter called "mode" to my actions, which I set in my ajax calls. If it is provided, I return a JsonViewResult. If it isn't supplied, I assume it was a standard Http post and I return a ViewResult.
I'd like to be able to use something similar to the IsMvcAjaxRequest in my controllers when using jQuery so I could eliminate the extra parameter in my Actions.
Is there anything out there that would provide this capability within my controllers or some simple way to accomplish it? I don't want to go crazy writing code since adding a single parameter works, it just isn't ideal.
Here's an except from MVC RC1 release notes - Jan 2009
IsMvcAjaxRequest Renamed to IsAjaxRequest
The IsMvcAjaxRequest method been
renamed to IsAjaxRequest. As part of
this change, the IsAjaxRequest method
was updated to recognize the
X-Requested-With HTTP header. This is
a well known header sent by the major
JavaScript libraries such as
Prototype.js, jQuery, and Dojo.
The ASP.NET AJAX helpers were updated to send this header in
requests. However, they continue to
also send it in the body of the form
post in order to work around the issue
of firewalls that strip unknown
headers.
In other words - it was specifically renamed to be more 'compatible' with other libraries.
In addition, for anyone who hasnt read the full release notes but has been using previous versions - even as recent as the beta - I STRONGLY recommend you read them in full. It will save you time in future and most likely excite you with some of the new features. Its quite surprising how much new stuff is in there.
Important note: You will need to make sure you upgrade the .js file for MicrosoftAjax.MVC (not the exact name) if upgrading to RC1 from the Beta - otherwise this method won't work. It isn't listed in the release notes as a required task for upgrading so don't forget to.
See Simons answer below. The method I describe here is no longer needed in the latest version of ASP.NET MVC.
The way the IsMvcAjaxRequest extension method currently works is that it checks Request["__MVCASYNCPOST"] == "true", and it only works when the method is a HTTP POST request.
If you are making HTTP POST requests throug jQuery you could dynamically insert the __MVCASYNCPOST value into your request and then you could take advantage of the IsMvcAjaxRequest extension method.
Here is a link to the source of the IsMvcAjaxRequest extension method for your convenience.
Alternatively, you could create a clone of the IsMvcAjaxRequest extension method called
IsjQueryAjaxRequest that checks Request["__JQUERYASYNCPOST"] == "true" and you could dynamically insert that value into the HTTP POST.
Update
I decided to go ahead and give this a shot here is what I came up with.
Extension Method
public static class HttpRequestBaseExtensions
{
public static bool IsjQueryAjaxRequest(this HttpRequestBase request)
{
if (request == null)
throw new ArgumentNullException("request");
return request["__JQUERYASYNCPOST"] == "true";
}
}
Checking from an action if a method is a jQuery $.ajax() request:
if (Request.IsjQueryAjaxRequest())
//some code here
JavaScript
$('form input[type=submit]').click(function(evt) {
//intercept submit button and use AJAX instead
evt.preventDefault();
$.ajax(
{
type: "POST",
url: "<%= Url.Action("Create") %>",
dataType: "json",
data: { "__JQUERYASYNCPOST": "true" },
success: function(data) {alert(':)');},
error: function(res, textStatus, errorThrown) {alert(':(');}
}
);
});
Why don't you simply check the "X-Requested-With" HTTP header sent automatically by most Javascript libraries (like jQuery) ?
It has the value 'XMLHttpRequest' when a GET or POST request is sent.
In order to test it you should just need to check the "Request.Headers" NameValueCollection in your action, that is :
if (Request.Headers["X-Requested-With"] == "XMLHttpRequest")
return Json(...);
else
return View();
This way, you can simply differentiate regular browser requests from Ajax requests.
Ok, I have taken this one step farther and modified my jQuery file to load the additional parameter into the post data, so I don't have to repeat the "__JQUERYASYNCPOST: true" for every call to post. For anybody that's interested, here's what my new definition for $.post looks like:
post: function(url, data, callback, type) {
var postIdentifier = {};
if (jQuery.isFunction(data)) {
callback = data;
data = {};
}
else {
postIdentifier = { __JQUERYASYNCPOST: true };
jQuery.extend(data, postIdentifier);
}
return jQuery.ajax({
type: "POST",
url: url,
data: data,
success: callback,
dataType: type
});
}
I added the "postIdentifier" variable as well as the call to jQuery.extend. Now the Helper explained in spoon16's response works without having to add any thing special to my page-level jQuery code.

Categories