How to make ajax calls in codeigniter HMVC - php

I am using Codeigniter version 3.0.6 with HMVC Moduler Extension. (MX). When i try to make a ajax call it showing me a error massage 403.
<script>
var site = '<?=site_url()?>';
$('#item-name').keyup(function(){
var d = $('#item-name').val();
$('#item-list').css('display','block');
$.post(site+"/moduleone/lists",{name: d}, function(data, status){
$('#item-list').html(data);
});
});
</script>
After executing this code i get and error in chrome console :
Failed to load resource: the server responded with a status of 403 (Forbidden)
Module Method:
public function lists()
{
echo 'afadfad';
exit();
}

I found the problem. I make codeigniter csrf true. That's why every time i submit a form it need a csrf token. But by the in ajax call there is no csrf token found that why it show the authentication error.
$config['csrf_protection'] = TRUE;
$config['csrf_token_name'] = 'csrf';
$config['csrf_cookie_name'] = 'csrf_cookie';
$config['csrf_expire'] = 7200;
$config['csrf_regenerate'] = TRUE;
$config['csrf_exclude_uris'] = array(
'moduleone/lists'
);
If you turn off (false the csrf_protection) then it work perfect.
if you want more information then check out the codeigniter user_guide.

In order to use base_url() and site_url() you have to load codeigniter url helper.Like this.
$this->load->helper('url');
or you can load it on application/config/autoload.php.Then make your ajax call like this...
<script type="text/javascript">
$(document).ready(function(){
url = '<? echo base_url('moduleone/lists');?>';
$('#item-name').on('keyup',function(){
var d = $('#item-name').val();
$('#item-list').css('display','block');
$.ajax({
type:'POST',
url:url,
data: {name: d},
success:function(data, status){
$('#item-list').html(data);
}
});
});
});
</script>
And in Controller use $this->input->post('name') to get your name sent from ajax call. Like this.
public function lists()
{
$name = $this->input->post('name');// name sent from ajax
echo $name;
}

Related

Failed to load resource errors(405) when send Ajax data to php

I have error ->
"Failed to load resource: the server responded with a status of 405
(Method Not Allowed)"
when send Ajax data to PHP in larval.
(I made route)
Ajax code
function insertData()
{
var text = document.getElementById('humanText').value;
var user = document.getElementById('userName').innerText;
$.ajax({
type:"POST",
url: "insertContentData",
data:{text:text, user:user},
success: function(data){
alert(data);
}
});
document.getElementById('humanText').value = "";
};
insertData();
and my php code "insertContentData.php"
<?php
$data = $_POST['text'];
$user = $_POST['user'];
echo $data.", ".$user;
?>
why not work this?
Thanks for your help.
In the http world the "METHOD" normally used is "GET" which is simply pulling data from the server. When you want to send data from the user to the server you used "POST". These are the two most commonly used methods.
The errors says that the METHOD IS NOT ALLOWED. You are AJAX code shows that you are using the POST method.
In Laravel you need to define a route that allows for the POST method. So instead of Route::get($uri, $callback); it would be Route::post($uri, $callback); Some more information can be found in the Laravel Routing documentation. However I think you are missing some concepts based on the primitive PHP code you posted, that code should be inside a controller.
Try to run like this. I hope it works.
function insertData(){
var text = document.getElementById('humanText').value;
var user = document.getElementById('userName').innerText;
$.ajax({
type:"POST",
url: "insertContentData",
data:{text:text, user:user},
success: function(data){
alert(data);
}
});
document.getElementById('humanText').value = "";
};
window.onload = function(){
insertData();
}
<?php
$data = $_POST['text'];
$user = $_POST['user'];
echo $data.", ".$user;
?>

Codeigniter not accepting jQuery POST with CSRF protection enabled

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

403 Forbidden Access to CodeIgniter controller from ajax request

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: {
},
},
});

Why it shows 403(forbidden) when making an ajax request?

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>

PUT request from Backbone to Slim REST service causes 404 Not Found

I have a backbone script that calls a Slim REST service. GET requests are working fine, PUT requests are returning 404 Not Found. Note: this was working until my code was recently moved to a different server (and it works locally), so I'm guessing it has something to do with an Apache config setting. Here's a snippet of the backbone script:
jQuery(document).ready(function ($) {
//define box model
var Box = Backbone.Model.extend({
url: function () {
var urlId = (this.id) ? this.id : "";
var myUrl = "/wp-includes/api/service.php/box/" + urlId;
return myUrl;
}
});
var BoxView = Backbone.View.extend({
tagName: "div",
template: $("#boxTemplate").html(),
initialize: function () {
this.model = new Box(box);
this.render();
},
saveBox: function(e){
e.preventDefault();
$("#boxMessage").empty();
var formData = {},
prev = this.model.previousAttributes();
$(e.target).closest("form").find(":input").not("button").each(function (){
var el = $(this);
formData[el.attr("id")] = el.val();
});
this.model.set(formData);
this.model.save(
{ },
{
success: function() {
$("#boxMessage").html("Box information saved.");
},
error: function() {
}
}
);
}
Here's a snippet of the Slim REST service:
<?php
require 'Slim/Slim.php';
$app = new Slim();
$app->get('/workouts/:id', 'getWorkout');
$app->put('/box/:id', 'updateEventBox');
$app->run();
function getWorkout($id) {
echo json_encode(GetEventCompetitorWorkout($id));
}
function updateEventBox($id) {
$request = Slim::getInstance()->request();
$body = $request->getBody();
$eventBox = new EventBox(null);
$eventBox->TakeJson($body);
$eventBox->Save();
}
And here's the header info for the request:
Request URL:http://www.mydomain.com/wp-includes/api/service.php/box/1
Request Method:PUT
Status Code:404 Not Found
UPDATE: just tested a POST to the same service and it worked fine. PUT still fails.
I've found it not too uncommon that some servers only have GET,POST,HEAD enabled and that PUT,DELETE which are needed for REST are not enabled. That could be the case.
To test for this you can tell Backbone to use "emulatated HTTP" by calling this before your code:
Backbone.emulateHTTP = true;
This will make backbone use only GET/POST requests however it will append to the querystring "_method=PUT" or "_method=DELETE" which you can use on the serverside to detect the intended HTTP verb.
So on the server side you need to do something like this like as the first line of your index.php file (before any of the framework loads):
if (isset($_REQUEST['_method'])) $_SERVER['REQUEST_METHOD'] = $_REQUEST['_method'];

Categories