Im having trouble with sending an ajax request to codeigniter controller. It is throwing back a 404 Forbidden Access error. I have found some sort of similar question to this but im not sure if its particular to CodeIgniter framework, and also the solution give in that thread did not solve my problem. below is my ajax request. Im wondering this is probably because of the .htaccess of the root folder of CI Application folder, but i dont want to change its default configuration yet.
Is sending ajax request to CI controller the correct way of implementing this? if not, any suggestion please. Thanks!
var ajax_load = '{loading gif img html}';
var ajax_processor = 'http://localhost/patientcare-v1/application/controller/ajax_processor/save_physical_info';
$("#save").click(function(){
$("#dialog-form").html(ajax_load);
$.post(
ajax_processor,
$("#physical-info").serialize(),
function(responseText){
$("#dialog-form").html(responseText);
},
"json"
);
});
CodeIgniter use csrf_protection, you can use it with Ajax and JQuery simply.
This (ultimate ?) solution work on multiple Ajax request (no 403 ;-) and preserve the security).
Change the configuration
Open the file /application/config/config.php
and change the line $config['csrf_token_name'] by :
$config['csrf_token_name'] = 'token';
You can use another name, but change it everywhere in future steps.
Add CSRF in your Javascript
Add script in a view; for me is in footer.php to display the code in all views.
<script type="text/javascript">
var CFG = {
url: '<?php echo $this->config->item('base_url');?>',
token: '<?php echo $this->security->get_csrf_hash();?>'
};
</script>
This script create an object named CFG. This object can be used in your Javascript code. CFG.url contain the url of your website and CFG.token ... the token.
Automatically renew the CSRF
Add this code in your part $(document).ready(function($){---}) as
$(document).ready(function($){
$.ajaxSetup({data: {token: CFG.token}});
$(document).ajaxSuccess(function(e,x) {
var result = $.parseJSON(x.responseText);
$('input:hidden[name="token"]').val(result.token);
$.ajaxSetup({data: {token: result.token}});
});
});
This script initialize the CSRF token and update it everytime when a request Ajax is sended.
Send the CSRF in PHP
I've created a new controller, named Ajax. In CodeIgniter, the link to use it is http://www.domain.ltd/ajax/foo
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Ajax extends CI_Controller {
public function foo() {
$this->send(array('foo' => 'bar'));
}
private function send($array) {
if (!is_array($array)) return false;
$send = array('token' => $this->security->get_csrf_hash()) + $array;
if (!headers_sent()) {
header('Cache-Control: no-cache, must-revalidate');
header('Expires: ' . date('r'));
header('Content-type: application/json');
}
exit(json_encode($send, JSON_FORCE_OBJECT));
}
}
The send function add the CSRF automatically and transform an array in object.
The final result
Now, you can use Ajax with JQuery very simply !
$.post(CFG.url + 'ajax/foo/', function(data) {
console.log(data)
}, 'json');
Result :
{"token":"8f65cf8e54ae8b71f4dc1f996ed4dc59","foo":"bar"}
When the request get data, the CSRF is automatically updated to the next Ajax request.
Et voilà !
Remove the <code> and application/controller from your ajax_processor like,
var ajax_processor = 'http://localhost/patientcare-v1/index.php/ajax_porcessor/save_physical_info';
If you are hiding index.php from url by using htaccess or routing then try this url,
var ajax_processor = 'http://localhost/patientcare-v1/ajax_porcessor/save_physical_info';
I was facing same problem but now I have fixed this problem.
First of all, I have created csrf_token in header.php for every pages like below code
$csrf = array(
'name' => $this->security->get_csrf_token_name(),
'hash' => $this->security->get_csrf_hash()
);
<script type="text/javascript">
var cct = "<?php echo $csrf ['hash']; ?>";
</script>
After that, when we are sending particular value through ajax then we will have to sent csrf token like below code
$.ajax({
url:"<?php echo APPPATHS.'staff_leave/leaveapproval/getAppliedLeaveDetails'; ?>",
data:{id:id,status:status,'<?php echo $this->security->get_csrf_token_name(); ?>': cct},
method:"post",
dataType:"json",
success:function(response)
{
alert('success');
}
});
I hope this code will help you because this is working for me.
// Select URIs can be whitelisted from csrf protection (for example API
// endpoints expecting externally POSTed content).
// You can add these URIs by editing the
// ‘csrf_exclude_uris’ config parameter:
// config.php
// Below setting will fix 403 forbidden issue permanently
$config['csrf_exclude_uris'] = array(
'admin/users/view/fetch_user', // use ajax URL here
);
$('#zero-config').DataTable({
"processing" : true,
"serverSide" : true,
"order" : [],
"searching" : true,
"ordering": false,
"ajax" : {
url:"<?php echo site_url(); ?>admin/users/view/fetch_user",
type:"POST",
data: {
},
},
});
Related
Good day. I'm working on a admin page basically it is a content management system. I want to delete the data based on their id. But unfortunately i've encounter a error on the htpp request. here is the error.
Request URL: admin/ajax_delete
Request Method:POST
Status Code:500 Internal Server Error
Remote Address:144.76.136.165:8181
VIEW FILE:
<span class="glyphicon glyphicon-trash"></span>
$("#delete_tpi").click(function() {
alert("Are you sure you want to delete?");
var tpi = $('.datatpi').val(); //package includes
var did = $('#data-id').val();
$.ajax({
url: '<?php echo site_url('admin/ajax_delete'); ?>',
type: 'POST',
datatype: 'html',
data: {id: did, tpi: tpi},
success:function (b){
if (b == 'Success') {
$('.#data-id').val('');
$('.datatpi').val('');
location.reload();
}
}
});
});
$('body').on('click','.edit-content-modal',function(){
var id = $(this).attr('data-id');
$('#data-id').val(id);
});
Controller file:
public function ajax_delete(){
$did = $this->input->post('id');
$ptpi = $this->input->post('tpi');
$update = $this->products_model->row_delete($did,$ptpi);
var_dump($update);
echo ($update)?'Success':'Fail';
}
MODEL FILE:
function ajax_delete($did,$ptpi){
$this->db->where('id',$did);
$this->db->delete('products',$ptpi);
return $this->db->affected_rows() > 0;
}
Because <a></a> element does not expect a value tag. You can get the ID of the clicked #delete_tpi link by using attr():
var did = $("#delete_tpi").attr('data-id');
Your POST request to admin/ajax_delete returns 500 Internal Server Error. This is a server-side error. If you use codeigniter, take a look at application/logs/*.log files that will give you detail information about the error.
I think, your problem is calling a non-existing function from model:
In your controller, you have:
$this->products_model->row_delete($did,$ptpi);
But your model, contains:
function ajax_delete($did,$ptpi){
....
}
Do you have row_delete() function in your model?
Once again, i suggest you to look at logs file, because many problems can result in server-side error.
I've been trying to POST to a Codeigniter controller (while CSRF protection is enabled) but this keeps failing with HTTP/1.1 500 Internal Server Error and This action is not allowed page.
I tried sending the csrf token along with POST data using the following method (which I found here) but it does not seem to work.
<script type="text/javascript" src="js/libs/jquery-2.1.1.min.js"></script>
<script type="text/javascript" src="js/libs/jquery.cookie.js"></script>
<div id="display">Loading...</div>
<script type="text/javascript">
// this bit needs to be loaded on every page where an ajax POST may happen
$.ajaxSetup({
data: {
csrf_token: $.cookie('csrf_cookie')
}
});
// now you can use plain old POST requests like always
$.post('http://localhost/index.php/handler/test', { name : 'Grim'}, function(data){ $('#display').html(JSON.stringify(data)); });
Here's my Codeigniter config.php file:
$config['csrf_protection'] = TRUE;
$config['csrf_token_name'] = 'csrf_token';
$config['csrf_cookie_name'] = 'csrf_cookie';
$config['csrf_expire'] = 1800;
Here's the controller:
function test()
{
echo json_encode($_POST);
}
add csrf token to data before posting
$.ajax({
type: "POST",
url: url,
data: {'<?php echo $this->security->get_csrf_token_name(); ?>':'<?php echo $this->security->get_csrf_hash(); ?>',/*----your data-----*/}
})
csrf token needs to be send along every request so it needs to be specified by the above echo statements
I've made an ajax call with this:
$('.start-rate-fixed').on('click', function(e){
e.preventDefault();
var videoRate = $('.start-rate input[name="rating"]:checked').val(),
productId = parseInt($('.popover-content').prop('id'));
$.ajax({
url : ROOT + 'products/rate_video',
type : 'POST',
data : {
'data[Product][id]' : productId,
'data[Product][success_rate]' : videoRate
}
}).done(function(res){
var data = $.parseJSON(res);
alert(data);
});
});
Where I defined ROOT as the webroot of my cakephp project in my default.ctp with this:
<script type="text/javascript">
var ROOT = '<?php echo $this->Html->url('/');?>';
</script>
and trying to retrieve data from a function "rate_video" defined in my products controller but I get this error. Also I've tried a simple ajax for a test function but it showed me the same issue.
Controller Code
public function rate_video(){
$this->autoRender = false;
if($this->request->is('post') && $this->request->is('ajax')){
$success_rate = $this->request->data['Product']['success_rate'];
$this->Product->id = $this->request->data['Product']['id'];
if($this->Product->saveField('success_rate', $success_rate)){
echo json_encode('Successfully Rated');
} else {
echo json_encode('Error!!');
}
}
}
Please add dataType and a forward slash (/) at the end of your request URL
$.ajax({
url : ROOT + 'products/rate_video/',
type : 'POST',
data : {
'data[Product][id]' : productId,
'data[Product][success_rate]' : videoRate
},
dataType: 'json',
}).done(function(res){
I just had the same problem and solved it by putting the URL within AJAX call to a URL that I know works. Then try accessing the URL that you are trying to invoke via AJAX directly within the web browser - most likely you are accessing a controller that does not have a view file created. To fix this you have to ensure that the controller method being accessed does not have a view to be rendered - set $this->render(null)
If you have incorrect url then
url: '<?php echo Router::url(array('controller' => 'Controllername', 'action' => 'actionname')); ?>'
this above url provide ajax to url from root to your action.
And other cause for 403 is your auth function, if your using auth in your controller then make your ajax function allow like
$this->Auth->allow('Your ajax function name here');
Your script placed at localhost/dev.popover/products/rate_video but ajax ROOT is / - that mean localhost/ and ajax sent request to
'localhost/products/rate_video'
Right solution is
<script type="text/javascript">
var ROOT = '<?php echo $this->Html->url('/dev.popover/');?>';
</script>
Fiddling inside CodeIgniter and trying to get a grip on it all as I've never worked with AJAX before.
For some reason, my AJAX is working perfectly when I use the GET method, but if I switch it over to the POST method, it stops working.
My JS:
$(document).ready(function(){
$('.love').click(function(event) {
$.ajax({
type: 'GET',
url: base_url + '/ajax/love_forum_post',
data: { post_id: 2, user_id: 1, ajax: 1 },
});
return false;
});
});
And my CONTROLLER:
function love_forum_post()
{
$post_id = $this->input->get('post_id');
$user_id = $this->input->get('user_id');
$is_ajax = $this->input->get('ajax');
if ($is_ajax)
{
$this->load->model('forums_model');
$this->forums_model->add_love($post_id, $user_id);
}
// If someone tries to access the AJAX function directly.
else
{
redirect('', 'location');
}
}
If I switch the type to 'POST' inside my JS and then catch it on the other end with $this->input->post() it doesn't work.
Any suggestions?
I have tested your code in 2 scenarios:
first - without csrf protection, and I see no reason for your code not to run properly.
To be able to test it easier, append $.ajax call with success response.
Something like this
success: function(response) {
alert(response);
}
And add response to your love_forum_post method.
echo print_r($this->input->post(), true);
This would give you clean view of what it going on in your method.
In my installation everything works just fine.
Second scenario is with csrf protection.
In this case add new param to your post object.
<?php if ($this->config->item('csrf_protection') === true) : ?>
post_data.<?php echo $this->security->get_csrf_token_name()?> = '<?php echo $this->security->get_csrf_hash()?>';
<?php endif ?>
This would make CI accept post from this url.
Hopefuly it would help.
Cheers
By any chance you have csrf_protection enabled?
If yes you need to send the token and the value key as post parameter along with post request.
Try to use this
$post_data = $_POST;
and print the post data using this
print_r($post_data);die();
and you can see there if you catch the post data;
Gudluck!!
I am building a registration form with jquery which should handle the request via Ajax.
My code:
$.ajax(
{
type: "POST",
url: "http://www.example.com/register.php",
data: $("#register-form").serialize(),
cache: false,
success: function(message)
{
$("#reg_notification").html(message).fadeIn(400);
}
});
Now the register.php should either output an error if for example the email address is not valid and this will be put into the div reg_notification. If no error is made, then the user should be redirected to a "welcome page". But it is important that this page is not allways static, so in other words, I can not use a location.href in the jquery code but want to use
header("Location: http://www.example.com")
in PHP. The problem is that the user wont be redirected but the content of www.example.com will be put inside the div reg_notification.
I found a similar problem here: How to manage a redirect request after a jQuery Ajax call but the difference is that there they are using json which I can not use due to my server and they are also redirecting inside the javascript and not in the php file.
Impossible with header redirection.
Use something like that:
...
success: function(message)
{
$("#reg_notification").html(message)
.fadeIn(400, function() {window.location = "url"});
}
or
success: function(response)
{
if (response.success) {
$("#reg_notification").html(response.message)
.fadeIn(400, function() {window.location = response.redirectTo; } );
} else {
// somethings else
}
}
in php:
header("Content-type: application/json");
echo json_encode(array(
"success" => true,
"message" => "some message",
"redirectTo" => "my url"
));
UPDATE
header redirect impossible because XMLHttpRequest transparently follows to redirect url for get result. See there