PATCH AJAX Request in Laravel - ajax

Is it possible to make AJAX PATCH requests to laravel, or am I restricted to POST? Laravel uses PATCH in input hidden fields, however, I am not using form elements—just buttons that should partially update a record when clicked (via an AJAX request).
How would the route look like for this?
Routes file
Route::patch('questions/{id}', 'QuestionController#update')->before('admin');
I am not sure if laravel routes support PATCH.
Controller
public function update($id) {
if (Request::ajax() && Request::isMethod('patch')) {
//partially update record here
}
}
JS
$('div#question_preview <some button selector>').click(function (event) {
$.ajax({
url: 'questions/'+question_id,
type: 'PATCH',
data: {status: 'some status'}
});
});
I am just looking for clarity, thanks!

Yeah, it's possible try
In Your JavaScript
$('#div#question_preview <some button selector>').click(function() {
$.ajax({
url: 'questions/'+question_id,
type: 'PATCH',
data: {status: <SOME VALUE I WANT>, _method: "PATCH"},
success: function(res) {
}
});
});
In Your Route
Route::patch('questions/{id}', 'QuestionController#update')->before('admin');
In your QuestionController Controller's update method
dd(Request::method());
You will see the respond like
string(5) "PATCH"
Read more about Request Information on Laravel doc.

It's possible!
You should need to provide an extra parameter in the form request called as _method with a value PATCH.
JS
$('div#question_preview <some button selector>').click(function (event) {
$.ajax({
url: 'questions/'+question_id,
type: 'PATCH',
data: {status: 'some status',_method: 'PATCH'}
});
});
You can provide a hidden input in the view file with the value PATCH for better readability
HTML
<input type="hidden" name="_method" value="PATCH">
If you are using FormData, you need to send the request as POST. The Laravel application will automatically get it as a PATCH request because you included #method('PATCH'). So your route and method for that will get triggered.
JS with FormData
$('div#question_preview <some button selector>').click(function (event) {
let form_data= new FormData();
form_data.append('status','some status');
form_data.append('_method','PATCH');
$.ajax({
url: 'questions/'+question_id,
type: 'POST',
data: form_data
});
});

Related

Ajax link does not send POST request

I have the following ajax link:
#Html.AjaxActionLink(item.Name, "https://test.testspace.space/storage/Data/stream?tokenValue=e58367c8-ec11-4c19-995a-f37ad236e0d2&fileId=2693&position=0", new AjaxOptions { HttpMethod = "POST" })
However, although it is set to POST, it seems that it still sends GET request.
UPDATE:
As suggested below, I also tried with js functuion like this:
function DownloadAsset() {
alert("downloading");
$.ajax({
type: "POST",
url: 'https://test.testspace.space/storage/Data/stream?tokenValue=add899c5-7851-4416-9b06-4587528a72db&fileId=2693&position=0',
success: function () {
}
});
}
However, it still seems to be GET request. Parameters must be passed as query and not in the body of the request because they are expected like that by the target action. I don't know why (it would be more natural to have GET request) but back-end developer designed it like this due to some security reason.
If I use razor form like this, then it works:
<html>
<form action="https://test.testspace.space/storage/Data/stream?tokenValue=2ec3d6d8-bb77-4c16-bb81-eab324e0d29a&fileId=2693&position=0" method="POST">
<div>
<button>Send my greetings</button>
</div>
</form>
</html>
However, I can not use this because I already have bigger outer form on the page and I'll end up with nested forms which is not allowed by razor/asp.
The only way is to use javascript but for some reason it does not make POST request.
#Html.AjaxActionLink will generate to <a> tag,and tag will only have HttpGet request method.If you want to send HttpPost with <a> tag,you can use it call a function with ajax,here is a demo:
link
<script>
function myFunction() {
$.ajax({
type: "POST",
url: "https://test.testspace.space/storage/Data/stream",
data: { tokenValue: "e58367c8-ec11-4c19-995a-f37ad236e0d2", fileId: "2693", position:0 },
success: function (data) {
}
});
</script>
Since you want to make a POST request, but the values need to be as query string params in the URL, you need to use jquery.Param.
see https://api.jquery.com/jquery.param/.
You should set the params, like below :
$.ajax({
url: 'your url',
type: 'POST',
data: jQuery.param({ tokenValue: "your token", fileId : "2693", position: 0}) ,
...
Try this instead,
First remove the action url from the from
Second put the result in the success function to return response
and for parameters, I always use FormData() interface to post with Ajax
And last don't forget to include dataType, contentType, processData to not get an unexpected behavior
your code will look like this
var form_data = new FormData();
form_data.append('tokenValue' ,'add899c5-7851-4416-9b06-4587528a72db&fileId=2693');
form_data.append('position' ,'position');
$.ajax({
type: "POST",
dataType: 'json',
contentType:false,
processData:false,
data: form_data,
url: 'https://test.testspace.space/storage/Data/stream',
success: function (result) {
}
});

Laravel ajax post not working even though CSRF token included

I am having difficulty getting an ajax post to work with laravel v5.5.24. Here is what my ajax call looks like:
var CSRF_TOKEN = $('meta[name="csrf-token"]').attr('content');
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
url: "/postCustomer?XDEBUG_SESSION_START=19683",
type: 'POST',
data: {_token: CSRF_TOKEN, message:myData, "_method": 'POST'},
dataType: 'JSON',
success: function (data) {
console.log('call to postCustomer successful');
}
});
Here is my route:
Route::post('/postCustomer','AdminUserController#store');
The interesting thing about this problem is that when all the post's are changed to get's (both in the ajax call and in the route) the request arrives and is handled correctly. The debug is triggered, and all is well. However, iof the route and the ajax call is set to POST, the debug is never triggered, and the request does not appear to make it. Naturally this smells like a CRSF issue, but I am including the CRSF token in the header.
if the javascript code inside .blade.php file try this
data: {_token:'{{ csrf_field() }}', message:myData, "_method": 'POST'},
hope its help
Try this,
<meta name="_token" content="{!! csrf_token() !!}"/>
$.ajaxSetup({
headers:
{'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content')}
});
$.ajax({
url: "/postCustomer?XDEBUG_SESSION_START=19683",
type: 'POST',
data: {message:myData, "_method": 'POST'},
dataType: 'JSON',
success: function (data) {
console.log('call to postCustomer successful');
}});
No need to pass token in ajax data again.
Heartfelt thanks to everyone who responded. A couple of things helpled in fuguring this thing out. First of all, I consolidated the CSRF token mentions,
and confined what I was sending as data to just that - no need to include the CSRF token in the data if you do it in the ajaxSetup. The second thing wasn't visible from my post, but I was encountering a race condition involving the button that triggered the ajax transaction. The button was causing a page reload before ajax could do its thing, and this is why occasionally the thing would appear to work, but mostly not. So the return false is necessary to prevent that - probably not in both places, but certainly after the ajax transaction has been invoked and we are waiting for the callback. The code which works can be found below. I hope it will prevent somebody else from spending a night going mad trying how to figure out what their POST's aren't working. Take away points: handle your CSRF in an ajaxSetup call, and return false from the whole business.
Thanks again to everybody.
-George Pipkin
Afton, Virginia
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
/* the route pointing to the post function */
url: "/postCustomer?XDEBUG_SESSION_START=19159",
type: 'POST',
/* send the csrf-token and the input to the controller */
data: {message:myData},
dataType: 'json',
/* remind that 'data' is the response of the AjaxController */
success: function (data) {
$("#success_msg").show();
return false;
}
});
return false;
You should have to pass the _token inside the data object.
data: {_token:'{{ csrf_token() }}',, message:myData, "_method": 'POST'},

NotFoundHttpException: No route found for "POST / in SYmfony2

I have an ajax posted form causing me to want to pull my hair having tried various answers based on almost similar problems here to no avail.
I have the following route in my routing.yml file
_save_profile:
pattern: /register/save-profile/{data}
defaults: {_controller: MYBundle:Registration:saveProfile}
requirements:
_method: GET|POST
options:
expose: true
and use the following code to post my form
var postData = $('#form').serializeArray();
$.ajax(
{
url: Routing.generate('_save_profile',{
type: "POST",
data : postData,
}).done(function()
{
alert("Saved");
});
Any help will be much appreciated.
You don't need send form data through parameter {data} in route. If you want send form with ajax, so you need.
Change route:
_save_profile:
pattern: /register/save-profile/
defaults: {_controller: MYBundle:Registration:saveProfile}
Change js:
var postData = $('#form').serializeArray();
$.ajax({
url: Routing.generate('_save_profile'),
type: "POST",
data: postData,
dataType: "json",
success:
function(result) {
console.log(result);
},
error:
function() {
alert('Error')
}
});
note: I don't use FOSJsRoutingBundle bundle for js routing. I always render route on template in data attribute. For example.
html
<form type="POST" id="form" data-url="path('_save_profile')">
js
var url = $('#form').data('url');
References
How to implement a simple Registration Form
FOSJsRoutingBundle documentation

Retrieve post value in the controller sent by ajax call

I am unable to retrieve value sent as a post through ajax call in cake php controller file
$.ajax({
type: "POST",
url: "share",
data: country,
dataType: "json",
success: function (response) {
if (response.success) {
// Success!
} else {
console.log(response.data, response.code);
}
}
});
I have tried with the below ways of retrieving the data sent in the above code through POST. But none of them worked.
$this->params
$this->data
$_POST[]
$this->request
The url points to the function in the controller page.
Please can any of you let me know how the value can be retrieved.
When submitting data via ajax and you want cake to pick it up in the usual way just use $('whatever').serialize().
if you don't have an actual form to serialize you can fake it by submitting the data as follows:
$.ajax({
...
data: {
data: country
},
...
});
Note how cake generates fields like data[Model][field]. you don't need the Model part but the data part is important.

joomla token is not getting recognized by controllers method

I'm trying to set up a token on ajax post but is not getting recognized by the controllers method. The javascrip looks as it follows
jQuery(document).ready(function() {
jQuery('#source').change(function() {
jQuery('#fileupload').addClass('fileupload-processing');
var data = jQuery('#source option:selected').val();
jQuery.post('index.php', {
'option': 'com_tieraerzte',
'task': 'parser.importColumns',
'tmpl': 'component',
'token':'<?php echo JUtility::getToken()?>',
'app': data,
'dataType': 'html',
}, function(result) {
jQuery('td.add_column').html(result);
jQuery('button#parse.btn').show();
//edit the result here
return;
});
});
the token is getting generated and posted
in the controller I check the existance of toke but throws me Invalid Token
controller check toke
JRequest::checkToken('request') or jexit( 'Invalid Token' );
You're almost there, it's just a little mixed up. The Joomla! Form Token is generated and submitted as a input name with a value of 1. So, the token looks like this in your form:
<input type="hidden" name="1LKJFO39UKSDJF1LO8UFANL34R" value="1" />
With that in mind, when submitting via AJAX, you need to set the parameter name to your token name, with a value of 1. I accomplish something similar by just using the jQuery('selector').serialize() method:
Joomla.autoSave = function () {
jQuery.ajax({
url: "index.php?option=com_gazebos&task=product.apply&tmpl=component",
type: "POST",
data: jQuery("#product-form").serialize(),
success: function (data) {
console.log("autosaved");
}
});
};
Doing this pulls in all the form data (including the form token from the hidden input) and formats it as a query string, then sends it with the request. However, it seems to me that you might not want to do that and you are really only wanting to submit a single bit of data, not the whole form. So, let's rework your code a little bit to get the desired effect:
/**
* First, let's alias $ to jQuery inside this block,
* then setup a var to hold our select list dom object.
*/
jQuery(document).ready(function ($) {
var sourceSelect = $('#source');
sourceSelect.change(function () {
$('#fileupload').addClass('fileupload-processing');
/**
* Use the token as a parameter name and 1 as the value,
* and move the dataType param to after the success method.
*/
$.post('index.php',
{
'option': 'com_tieraerzte',
'task': 'parser.importColumns',
'tmpl': 'component',
'app': sourceSelect.val(),
'<?php echo JSession::getFormToken()?>': 1
},
function(result) {
$('td.add_column').html(result);
$('button#parse.btn').show();
//edit the result here
return;
},
'html'
);
});
});
Finally, this code is assuming you have this js code either in your view.html.php or in your views/parser/tmpl/default.php. If you have it in a separate .js file, then your php code won't execute and give you the token.
In your ajax call method use url as :
$.ajax({
url: '/index.php?option=com_itemreview&task=item.userReviewVote&<?php echo JSession::getFormToken(); ?>=1',
type: 'post',
data: {'data': submitvalue},
dataType: 'json',
success: function(response) {
}
});
for more information see here:
http://joomlabuzz.com/blog/27-preventing-cross-site-request-forgery-in-joomla
https://docs.joomla.org/How_to_add_CSRF_anti-spoofing_to_forms

Resources