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);
};
Related
I am learning to use jQuery Ajax. What does function(response) mean and what is the meaning of response == 1 and response == 2?
jQuery.post(ajaxurl, data, function(response) {
if (response == 1) {
$saveAlert.addClass('is-success').delay(900).fadeOut(700);
setTimeout(function() {
$tieBody.removeClass('has-overlay');
}, 1200);
} else if (response == 2) {
location.reload();
} else {
$saveAlert.addClass('is-failed').delay(900).fadeOut(700);
setTimeout(function() {
$tieBody.removeClass('has-overlay');
}, 1200);
}
});
I'll explain the basics:
jQuery.post = You want to post some data to your endpoint
ajaxurl = your endpoint address. Typically a API
data = the data you want to send to your endpoint along with the request.
function(response) is where you handle the response from the endpoint.
So lets go through the code. First you call post to your endpoint / API with the data you want to post. Then you provide a callback (in your case a function) to handle the response the endpoint / API provides you.
In your case it looks like if the endpoint responds with 1, you have successfully posted your data. If the endpoint responds with 2, you have posted data and want to reload the site. If the endpoint does NOT respond with either 1 or 2, it failed to post.
To help you understand the basics of jQuery post:
A well-written API / endpoint should respond with the correct HTTP status codes and status messages and it should be fairly easy to notice when data was posted correctly and when an error occurred.
I don't think your endpoint responds any good. response == 1 or response == 2is not by any means clear and easy to understand.
A better way of handling success and errors is to use the done and fail handlers of jquery post (more on this below).
$.post( "test.php" );
This will completely ignore the response from calling the endpoint. I.e. you don't want to handle either success or error. PLEASE DO NOT USE THIS. You should handle success and error!
$.post( "test.php", function( data ) {
//Do something now
});
This will do whatever you provide in the function when the endpoint has sent its response.
$.post( "example.php", function() {
//You successfully reached the endpoint
console.log( "success" );
})
.done(function() {
//Handle success here!
})
.fail(function() {
//Handle error here
})
This is probably the preferred way of handling both success and errors. It's pretty clear that if you reach the fail, it has failed. Both easy to read the code and easy to understand jquery post!
The examples above is copied from the jquery documentation.
Note that the previous handlers for done and fail was success and error, but success and error is deprecated and removed in jQuery 3.0!
So if you have jQuery version < 3.0 you need to find out if you need to use the new or old syntax, or if you need to update jQuery maybe?
Hope this explains enough to make you understand the basics, and to help you get further. I highly suggest you read the jQuery.post documentation here. I think you should also read the w3schools documentation here.
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/
I am using the following tag to let the users like the post
Like
I get the id of the <a> through Javascript which is actually the post_id and send the data to like.php using the following GET method.
post_id = 22;
xrequest.open("GET","like.php?post_id="+post_id+",true);
xrequest.send();
I have two questions
How can I send this request using POST Method?
(Note that there is not any <form>...</form> around the tag.)
If I use the above mentioned GET Method, Is it secure?
Since you've tagged jQuery, I assume you are using it. If so, you can do it like:
// attach a click handler for all links with class "like"
$('a.like').click(function() {
// use jQuery's $.post, to send the request
// the second argument is the request data
$.post('like.php', {post_id: this.id}, function(data) {
// data is what your server returns
});
// prevent the link's default behavior
return false;
});
Regarding your second question: No, it does not really make it safer unless you are doing it within SSL (https). a middle-man can still intercept your message mid-way and read the contents. POST makes it more indirect (to intercept and read the payload) than GET, but not safer.
To use POST to send the like link id you can do the following:
$(document).ready(function() {
$("a.like").click(function(event) {
var data = event.target.id;
$.ajax({
type: "POST",
url: "like.php",
data: data
});
});
});
updated, there was a typo in my code.
If i understand your question correctly, something like this should work for you:
$('#link_22').click(function(){
var link = $(this).attr('id');
$.post('/like.php/', {post_id: link});
return false;
})
Then you can reach this from PHP with something like:
$_POST['post_id'];
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
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.