forbidden in ajax call error function in codeigniter csrf - ajax

I'm just getting started with codeigniter I want to insert some data into database via ajax but I have a problem with my ajax call;
I've been searching for two hours but I could not solve the problem.
My problem is when I click on submit button it says forbidden.
Also my csrf protection is set to TRUE! Please help, thanks
JS
$(document).ready(function() {
$(".addbtn").click(function (e) {
e.preventDefault();
if($("#mname").val()==='' ||
$('#sname').val() === '' ||
$('#genre').val()==='' ||
$('#album').val()==='' ||
$('#publishyear').val() ==='' ||
$('#artist').val()==='')
{
alert("Please fill all the fields!");
return false;
}
$("#FormSubmit").hide();
$("#LoadingImage").show();
var baseurl = "<?php echo base_url(); ?>";
var data = {
'mname': $("#mname").val(),
'sname': $('#sname').val(),
'genre': $('#genre').val(),
'album': $('#album').val(),
'publishyear': $('#publishyear').val(),
'artist': $('#artist').val(),
'<?php echo $this->security->get_csrf_token_name(); ?>':
'<?php echo $this->security->get_csrf_hash(); ?>'
};
$.ajax({
type: "POST",
url: baseurl+"index.php/admin_page/send_ajax",
data: data,
success:function(){
alert("success");
},
error:function (xhr, ajaxOptions, thrownError){
$("#FormSubmit").show();
$("#LoadingImage").hide();
alert(thrownError);
}
});
});});
Config file
$config['csrf_protection'] = TRUE;
$config['csrf_token_name'] = 'csrf_test_name';
$config['csrf_cookie_name'] = 'csrf_cookie_name';
$config['csrf_expire'] = 7200;
$config['csrf_regenerate'] = TRUE;
$config['csrf_exclude_uris'] = array();
Controller
public function send_ajax(){
$data = array(
'name_of_music'=>$this->input->post("mname", TRUE),
'artist'=>$this->input->post("artist", TRUE),
'name_of_singer'=>$this->input->post("sname", TRUE),
'genre'=>$this->input->post("genre", TRUE),
'album'=>$this->input->post("album", TRUE),
'publishyear'=>$this->input->post("publishyear", TRUE)
);
$json_data['lyrics_info_data'] = json_decode($data);
$this->user_model->insert_json_in_db($json_data);
}
Model
public function insert_json_in_db($json_data){
$this->db->insert('lyrics', $json_data);
}

Can you confirm what is the use of this line $json_data['lyrics_info_data'] = json_decode($data); ? I think error is with this line.
You may use $json_data['lyrics_info_data'] = $data; instead of $json_data['lyrics_info_data'] = json_decode($data);
Also the model function need to update.
public function insert_json_in_db($json_data){
$this->db->insert('lyrics', $json_data['lyrics_info_data']);
}
Script update
Codeigniter will regenerate its crcf token on each request and this info will be stored in cookie. So token value you need to take from cookie and send along with ajax data you are passing. What I am doing with folliwing javascript is that, using a common function to attach crcf value along with all the ajax request.
In jquery there is an option to add custom data along with ajax request.
See jquery documentation http://api.jquery.com/jquery.ajaxprefilter/ for more details
<script>
$(document).ready(function(){
function getCookie(c_name) { // A javascript function to get the cookie value
if(document.cookie.length > 0) {
c_start = document.cookie.indexOf(c_name + "=");
if(c_start != -1) {
c_start = c_start + c_name.length + 1;
c_end = document.cookie.indexOf(";", c_start);
if(c_end == -1) c_end = document.cookie.length;
return unescape(document.cookie.substring(c_start,c_end));
}
}
return "";
}
$.ajaxPrefilter(function(options, originalOptions, jqXHR){ // This function will attach "csrf_test_name" with all the request you are sending.
if (options.type.toLowerCase() === "post") { // Required only if its a post method
var csrf_token = getCookie("csrf_test_name");
// initialize `data` to empty string if it does not exist
options.data = options.data || "";
// add leading ampersand if `data` is non-empty
options.data += options.data?"&":"";
// add _token entry
options.data += "csrf_test_name=" + csrf_token;
}
});
});
</script>
You can remove '<?php echo $this->security->get_csrf_token_name(); ?>': '<?php echo $this->security->get_csrf_hash(); ?>' from var data.
Important note: if you change $config['csrf_token_name'] = 'csrf_test_name'; in config.php then you need to update this script as well.
Please try after updating your code and let me know if issues still exists.

Make Sure you are getting right base_url() and in javascript you should define the base_url() globally somewhere so that you can access it in any script as below
var baseurl = <?php echo base_url() ?>;
`

You are going way out of your way to make this difficult. csrf is not your problem. Try something like this
$(function () {
"use strict";
$("#form2").submit(function () {
var data = $("#form2").serialize();
//alert(data); return false;
$.ajax({
url: "/log/login",
data: data,
type: "POST",
success: function (msg) {
$("#display").text(msg);
},
error: function (msg) {
$("#display").text("its all bad");
}
});
return false;
});
});
(Of course you will need to put your own form id in etc)
Your controller should look something like this:
$data = array(
'borncity' => htmlspecialchars(trim($this->input->post('borncity'))),
'state' => htmlspecialchars(trim($this->input->post('state'))),
'country' => htmlspecialchars(trim($this->input->post('country'))),
'family' => htmlspecialchars(trim($this->input->post('family'))),
'year' => htmlspecialchars(trim($this->input->post('year'))),
'state1' => htmlspecialchars(trim($this->input->post('state1'))),
'deathcity' => htmlspecialchars(trim($this->input->post('deathcity')))
);
$this->form_validation->set_rules('borncity', 'city of birth', 'required|trim');
$this->form_validation->set_rules('state', 'state', 'required|trim');
$this->form_validation->set_rules('country', 'country', 'required|trim');
$this->form_validation->set_rules('family', 'family', 'required|trim');
$this->form_validation->set_rules('year', 'year', 'required|trim');
$this->form_validation->set_rules('state1', 'Born State', 'required|trim');
$this->form_validation->set_rules('deathcity', 'Death City', 'trim');
if( $this->form_validation->run() == FALSE) {
echo validation_errors();
}else
{
$this->db->insert('cities', $data);
echo "Success"; //this will show up in your ajax success line
}
}
Use Codeigniter's form validation in your controller. You do not need to use json decode. Please note these are examples

Related

How to parse an object passed by an AJAX?

I made an Ajax POST request into my Laravel function however i am facing this result:
<script> Sfdump = window.Sfdump || (function (doc) { var refStyle = doc.createElement('style')
This happens when i die and dump my data so as to see what i get from ajax request. I have this jquery method:
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$('#save-person').on('click', function() {
let first_name = $('#first_name').val();
let middle_name = $('#middle_name').val();
let third_name = $('#third_name').val();
let family_name = $('#family_name').val();
$.ajax({
url: urlReq+"/api/employee/customize",
type: "POST",
data: {
first_name: first_name,
middle_name: middle_name,
third_name: third_name,
family_name: family_name,
},
cache: false,
success: function(dataResult){
console.log(dataResult);
let data = dataResult;
if(data.statusCode==200){
$("#success").show();
$('#success').html('Data added successfully !');
}
else if(dataResult.statusCode==201){
alert("Error occured !");
}
}
});
});
and on my php method i have this:
public function customize_store(Request $request){
//dd($request->first_name);
$input = $request->all();
dd($input);
return response()->json(['Person'=>$input]);
}
which result to <script> Sfdump = window.Sfdump || (function (doc) { var refStyle = doc.createElement('style'), rxEsc = /([.*+?^${}()|\[\]\/\\])/g, idRx =... but my input are also present there that looks like this:
#<span class=sf-dump-protected title="Protected property">parameters</span>: <span class=sf-dump-note>array:15</span> [<samp>
"<span class=sf-dump-key>first_name</span>" => "<span class=sf-dump-str title="7 characters">Michael</span>"
"<span class=sf-dump-key>middle_name</span>" => "<span class=sf-dump-str title="6 characters">Sangga</span>"
"<span class=sf-dump-key>third_name</span>" => <span class=sf-dump-const>null</span>
"<span class=sf-dump-key>family_name</span>" => "<span class=sf-dump-str title="7 characters">Smith</span>"
How would i extract those data so that i can persist it on my database?
Try this code.. check the URL, Routes on which you are sending your
data..
public function addPersonData(Request $request){
$save_person = new Person(); // Initialize your model here..
$save_person->first_name = $request->get('first_name');
$save_person->middle_name = $request->get('middle_name');
$save_person->third_name = $request->get('third_name');
$save_person->family_name = $request->get('family_name');
$save_person->save();
return 'ok';
}
I think I got it. First add a name to your route (see here) and the ajax part in your jQuery (assuming you use a form to submit the user data):
in your Route.php add:
Route::post('api/employee/customize', 'PersonController#customize_store')->name('api.employee.customize');
Your jQuery ajax request:
$('#save-person').submit(function(e) {
e.preventDefault();
let first_name = $('#first_name').val();
let middle_name = $('#middle_name').val();
let third_name = $('#third_name').val();
let family_name = $('#family_name').val();
$.ajax({
url: "{{ route('api.employee.customize') }}",
type: "POST",
data: { first_name, middle_name, third_name, family_name },
cache: false,
success: function(data){
console.log(data);
if(data.status === 'success'){
$("#success").show();
$('#success').html('Data added successfully !');
//the person's details are in data.person.first_name etc
//you already knew that, but added is the new data.person.id you may use
}
else {
alert("Error occured !");
}
}
});
});
and your controller, assuming the model linked to this data is Person:
public function customize_store(Request $request){
$person = new Person($request->all());
if ($person->save()) {
return response()->json(['status' => 'success', 'person'=>$person]);
}
return response()->json(['status' => 'fail']);
}

added a new record using ajax and codeigniter.i want to redirect to the view page after adding record. so i want to get the last insert id

Ajax function and controller action is given below.anyone can help to get the last insertid to redirect.the redirection is done in ajax success function. can it do in controller action.its not getting
Ajax function
<script type="text/javascript">
$('#rfqsubmit').click(function () {
//var title = $('#title').val();
var form_data = {
title: $('#txtname').val(),
merid: $('#mermerchant').val(),
userid: $('#customer').val(),
description: $('#txtrequirement').val(),
reqid: $('#requirementid').val(),
shipmethod: $('#shipmethod').val(),
shiplocation: $('#shiplocation').val(),
attachment: $('#txtattachments').val(),
bidclose: $('#txtbidclose').val(),
ajax: '1'
};
$.ajax({
url: "<?php echo base_url() ?>moderator/RFQ/addoffline",
type: 'POST',
data: form_data,
success: function () {
window.location.href ="<?php echo base_url() ?>moderator/Employee/manageemployee/";
// window.location.href ="<?php //echo base_url() ?>moderator/RFQ/viewrfq/"+ form_data.reqid;
// alert('added Successfully');
}
});
return false;
});
</script>
Controller action
$this->load->helper(array('form', 'url'));
$this->load->helper('file');
$data7 = array(
'rfq_title' => $this->input->post('title'),
'rfq_detail' => $this->input->post('description'),
'rfq_merchantid' => $this->input->post('merid'),
'rfq_userid' => $this->input->post('userid'),
);
$add= $this->requirement_model->forminsert($data7);
}
Your question is not clear anyhow if i got what you need try this.
in your controller action return json response:
$this->load->helper(array('form', 'url'));
$this->load->helper('file');
$data7 = array(
'rfq_title' => $this->input->post('title'),
'rfq_detail' => $this->input->post('description'),
'rfq_merchantid' => $this->input->post('merid'),
'rfq_userid' => $this->input->post('userid'),
);
$inserted_id= $this->requirement_model->forminsert($data7);
//your forminsert method in model should return
//$this->db->insert_id();
$response=array('id'=>$inserted_id,'message'=>"inserted successfully");
echo json_encode($response);
die();
}
Your model function return last_inserted_id:
public function forminsert($data7)
{
$this->db->insert('jil_mrorfq',$data7);
//it will return last id
return $this->db->insert_id();
}
Now in ajax success :
$.ajax({
url: "<?php echo base_url() ?>moderator/RFQ/addoffline",
type: 'POST',
data: form_data,
dataType:"Json",
success: function (data) {
//to access that id
var last_inserted_id = data.id;
window.location.href ="<?php echo base_url() ?>moderator/Employee/manageemployee/"+last_inserted_id;
}
});

Ajax response Not working in Codeigniter

I want to show tick.png image on clicking save button when data inserted in database successfully. My view file name is insert_your_committee, model is users_model & controller user
Here is my code of all there files:
My Script of my insert_your_commitee file, All console.log show correct result but success function is not working. What is the problem?
<script>
function save_committee($c_id,$m_id,$start_date){
console.log($c_id);
console.log($m_id);
console.log($start_date);
var mid=$('#irnum'+$start_date).val();
console.log("df"+mid);
var url= "<?php echo site_url("user").'/ref_add';?>";
$.ajax({
url: url,
type: "POST",
dataType:'json',
data: {c_id:$c_id,m_id:$m_id,start_date:$start_date,irnum:mid},
success: function(data){
console.log(data);
$('#'+$start_date).show();
$('#btn'+$start_date).hide();
}
});
}
</script>
My Controller
public function ref_add()
{
$this->load->model('Users_model');
$parms=$this->input->post();
$c_id=$this->input->post('c_id');
$m_id=$this->input->post('m_id');
$s_dateparms=$this->input->post('start_date');
$irnum=$this->input->post('irnum');
$data_to_store = array(
'Cid' =>$c_id,
'Mid' =>$m_id,
'Month' => $s_dateparms,
'Year'=>$s_dateparms,
'Ref_Number' =>$irnum,
);
$params=array();
if ($this->users_model->add_ref($data_to_store)) {
$params['status'] = TRUE;
} else {
$params['status'] = false;
}
$return["json"] = json_encode($params);
echo json_encode($return);
}
And Here is my model
function add_ref($data)
{
$this->db->insert('reference', $data);
$report = array();
$report['error'] = $this->db->_error_number();
$report['message'] = $this->db->_error_message();
if($report !== 0){
return true;
}else{
return false;
}
}
I am not completely sure, but in order to get ajax to work, I had to add return false; after the ajax call in the function.
In my case, I was using ajax for login and backend was in codeigniter.

Unable to get_the_content(); of a post in Wordpress via AJAX

I'm trying to ajaxify my Wordpress theme and I use the ajax-in-WordPress method and I'm now trying get_the_content of post via functions.php. Using jQuery, when I do alert(data) I get the 'title' echo but not the content of the existing post I want (returns 0).
What am I doing wrong?
The jQuery part
$('.ajaxed,.ajaxed a,.menu-item-home a,.menu-item-object-page a').live('click', function(event) {
event.preventDefault();
var link = $(this).attr('href');
var toRemove = MySettings.url;
var rewritepath = link.replace(toRemove,'');
var handler = function(data) {
$('title').html($('title', data).html());
$('#primary').html($('#primary', data).html());
$('#primary').hide().fadeIn('slow');
$.address.title(/>([^<]*)<\/title/.exec(data)[1]);
};
$.post(ajax_object.ajaxurl, {
action: 'ajax_action',
post_id: $(this).find('input.post_id').attr('value')
},function(data) {
alert(data.post_title);
alert(data.post_content);
});
/*$.ajax({
url: link,
error: function(XMLHttpRequest, textStatus, errorThrown) {
handler(XMLHttpRequest.responseText);
},
success: function(data, textStatus, XMLHttpRequest) {
handler(data, function(){
});
}
});*/
$.address.state(MySettings.path).crawlable(true).value(rewritepath);
return false;
});
The functions.php part
<?php
function javascripts() {
if( !is_admin()){
$blogurl = get_bloginfo('url');
$thumbnail_width = get_option('thumbnail_size_w');
$thumbnail_height = get_option('thumbnail_size_h');
$path = parse_url(get_bloginfo('siteurl'), PHP_URL_PATH);
$url = 'http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js';
wp_deregister_script('jquery');
if (get_transient('google_jquery') == true) {
wp_register_script('jquery', $url, array(), null, true);
}
else {
$resp = wp_remote_head($url);
if (!is_wp_error($resp) && 200 == $resp['response']['code']) {
set_transient('google_jquery', true, 60 * 5);
wp_register_script('jquery', $url, array(), null, true);
}
else {
set_transient('google_jquery', false, 60 * 5);
$url = get_bloginfo('wpurl') . '/wp-includes/js/jquery/jquery.js';
wp_register_script('jquery', $url, array(), '1.7', true);
}
}
wp_enqueue_script('plugins.js', get_bloginfo('template_directory') . "/js/plugins.js" , array('jquery'));
wp_enqueue_script('ajax-script', get_bloginfo('template_directory') . "/js/scripts.js", array('jquery'));
wp_localize_script('ajax-script', 'ajax_object', array('ajaxurl' => admin_url( 'admin-ajax.php' )));
wp_localize_script('jquery', 'MySettings', array('width' => $thumbnail_width,'height' => $thumbnail_height,'url' => $blogurl,'path' => $path));
}
}
add_action('wp_enqueue_scripts', 'javascripts');
add_action('wp_ajax_ajax_action', 'ajax_action_stuff'); // ajax for logged in users
add_action('wp_ajax_nopriv_ajax_action', 'ajax_action_stuff'); // ajax for not logged in users
function ajax_action_stuff() {
$post_id = $_POST['post_id'];
update_post_meta($post_id, 'post_key', 'meta_value'); //not sure why you need this
$post_data = get_post($post_id);
echo json_encode($post_data);
}
?>
What am I doing wrong? Thanks
Without seeing the entire scope of your code, it appears that you might be calling get_the_content() outside of the context of The Loop. If so, the function doesn't understand which post you'd like to retrieve the content for. Try organizing the function this way:
function ajax_action_stuff() {
$post_id = $_POST['post_id'];
update_post_meta($post_id, 'post_key', 'meta_value'); //not sure why you need this
$post_data = get_post($post_id);
$title = $post_data->post_title;
$content = $post_data->post_content;
echo $title;
echo $content;
}
Here we've used get_post() to return an object with all of the post data.
The jQuery function you've created...
function(data) {
alert(data);
});
... should essentially contain a string in the data object that contains your title and content.
Here's a recommendation though, on how you can return your data in a more organized fashion, if you like.
The 'data' object (which is what you've echoed in the php function ajax_action_stuff()) is just a string value. The problem though is that the data isn't really structured in a way for jQuery to fully understand and use to its full potential. If you change your php function to return a JSON object though, then you can use all your properties in jQuery individually. I'll show you how...
function ajax_action_stuff() {
$post_id = $_POST['post_id'];
update_post_meta($post_id, 'post_key', 'meta_value'); //not sure why you need this
$post_data = get_post($post_id);
echo json_encode($post_data);
}
Then in the jQuery function you have access to each property like this:
$.post(ajax_object.ajaxurl, {
action: 'ajax_action',
post_id: $(this).find('input.post_id').attr('value')
},function(data) {
alert(data.post_title);
alert(data.post_content);
});
Have a look at the get_post() function to see all of the properties that you have available to you.
You aren't telling get_the_content() which post to retrieve the content for. Internally, this function checks for the global $post object and filters the content of that object.
So change your ajax function to something like this:
function ajax_action_stuff() {
global $post;
$post_id = $_POST[ 'post_id' ];
update_post_meta( $post_id, 'post_key', 'meta_value' );
$post = get_post( $post_id );
$title = 'title';
$content = get_the_content();
echo $title;
echo $content;
}
This will use the ID you've passed in to query the database for a specific post and populate the global $post object. Now, get_the_content() and even get_the_title() should function normally.

Ajax Form submit

I am new to Ajax. i wanna submit a form through Ajax and save the data sent to the database.
Something like the Facebook Status update - where text area is disabled and then submited. once its saved in the database it comes back and updates the status message on the top. and again the text area is enabled.
this is my form
<?php echo $form->create('StatusMessage', array('type' => 'post', 'url' => '/account/updateStatus', 'id' => 'updateStatus')); ?>
<?php echo $this->Form->input('id', array('value' => $user['User']['id'],'type' => 'hidden')); ?>
<?php echo $this->Form->textarea('message', array('value' => 'What have you been eating ?')); ?>
Edited: Modified as suggested by 0 RioTera
Cakephp Action
function updateStatus() {
$this->autoRender = false;
if($this->RequestHandler->isAjax()) {
$this->layout = 'ajax'; //THIS LINE NEWLY ADDED
$this->data['StatusMessage']['pid'] = 0;
$this->data['StatusMessage']['commenters_item_id'] = $this->data['StatusMessage']['item_id'] = $this->User->Item->itemId('1', $this->data['StatusMessage']['id']);
unset($this->data['StatusMessage']['id']);
//debug($this->data);
if($this->User->Item->StatusMessage->save($this->data)) {
return true;
} else {
echo 'not saved';
}
} else {
echo 'no';
}
}
Javascript code
$(document).ready(function () {
var options = {
target: '#output2',
// target element(s) to be updated with server response
beforeSubmit: showRequest,
// pre-submit callback
success: showResponse, // post-submit callback
// other available options:
//url: url // override for form's 'action' attribute
//type: type // 'get' or 'post', override for form's 'method' attribute
//dataType: null // 'xml', 'script', or 'json' (expected server response type)
clearForm: true // clear all form fields after successful submit
//resetForm: true // reset the form after successful submit
// $.ajax options can be used here too, for example:
//timeout: 3000
};
$('#updateStatus').submit(function () {
// make your ajax call
$(this).ajaxSubmit(options);
return false; // prevent a new request
});
function showRequest(formData, jqForm, options) {
$('#StatusMessageMessage').attr('disabled', true);
}
function showResponse(responseText, statusText, xhr, $form) {
$('#StatusMessageMessage').attr('disabled', false);
alert('shdsd');
}
});
Using jquery and http://jquery.malsup.com/form/ plugin:
$(document).ready(function() {
var options = {
target: '#message', // target element(s) to be updated with server response
beforeSubmit: showRequest, // pre-submit callback
success: showResponse // post-submit callback
};
$('#updateStatus').ajaxForm(options);
});
function showRequest(formData, jqForm, options) {
$('#StatusMessageMessage').attr('disabled', true);
}
function showResponse(responseText, statusText, xhr, $form) {
$('#StatusMessageMessage').attr('disabled', false);
}
I didn't try it but I hope it helps you
i hope that this tutorial will help
http://mohammed-magdy.blogspot.com/2010/10/ajaxformsubmitter.html
This is a function I use to submit forms in cakephp 3.x it uses sweet alerts but that can be changed to a normal alert. It's very variable simply put an action in your controller to catch the form submission. Also the location reload will reload the data to give the user immediate feedback. That can be taken out.
$('#myForm').submit(function(e) {
// Catch form submit
e.preventDefault();
$form = $(this);
// console.log($form);
// Get form data
$form_data = $form.serialize();
$form_action = $form.attr('action') + '.json';
// Do ajax post to cake add function instead
$.ajax({
type : "PUT",
url : $form_action,
data : $form_data,
success: function(data) {
swal({
title: "Updated!",
text: "Your entity was updated successfully",
type: "success"
},
function(){
location.reload(true);
});
}
});
});
This is what a simple action would look like in the controller;
public function updateEntity($id = null){
$entity = $this->EntityName->get($id);
$entity = json_encode($this->request->data);
$this->EntityName->save($entity);
}

Resources