File uploading is a vital function in web development that allows users to share and store files on a server. CodeIgniter 4, a powerful PHP framework, offers developers a robust environment for creating web applications.
By leveraging the simplicity of jQuery AJAX and the capabilities of CodeIgniter 4, you can easily build an efficient file upload system without any complications.
In this tutorial, we will explore how to upload files using jQuery AJAX in CodeIgniter 4 and display a preview of the uploaded file. We will guide you through the process of setting up a CodeIgniter 4 project, creating a controller to handle file uploads, and implementing an upload form view.
Through this tutorial, you will learn how to leverage the capabilities of CodeIgniter 4 and jQuery AJAX to create a smooth and interactive file upload functionality.

Table of Content
- Enable CSRF
- Configure Routes
- Create a Controller – Handle file upload request
- View – Create HTML form & Write AJAX code for file upload
- Output
- Conclusion
1. Enable CSRF
- Open
.envfile. - Remove # from the start of the
security.tokenName,security.headerName,security.cookieName,security.expires,andsecurity.regenerate. - I update the
security.tokenNamevalue with'csrf_hash_name'. With this name read CSRF hash. You can update it with any other value. - If you don’t want to regenerate CSRF hash after each AJAX request then set
security.regenerate = false.
security.tokenName = 'csrf_hash_name' security.headerName = 'X-CSRF-TOKEN' security.cookieName = 'csrf_cookie_name' security.expires = 7200 security.regenerate = true
- Open
app/Config/Filters.phpfile and uncomment'csrf'in'before'if commented.
// Always applied before every request
public $globals = [
'before' => [
// 'honeypot',
'csrf',
// 'invalidchars',
],
'after' => [
'toolbar',
// 'honeypot',
// 'secureheaders',
],
];
2. Configure Routes
- Open
app/Config/Routes.phpfile. - Define 2 routes –
- / – Display file upload view.
- users/fileUpload – It is used to upload a file.
$routes->get('/', 'UsersController::index');
$routes->post('users/fileUpload', 'UsersController::fileUpload');
3. Create a Controller – Handle file upload request
- Create
UsersControllercontroller using the following command:
php spark make:controller UsersController
- Open the file and define two methods:
- index() – Load
indexview. - fileUpload() – Handles the AJAX request.
- index() – Load
Generate a new CSRF token and assign it to $data['token'].
Implement file validation using the following rules:
'file' => 'uploaded[file]|max_size[file,1024]|ext_in[file,jpeg,jpg,docx,pdf],'
If the file fails validation, assign 0 to $data['success'] and the validation response to $data['error'].
If the file is validated then read the file name and extension and upload the file to the "public/uploads" location. Assign 1 to $data['success'], 'Uploaded Successfully!' to $data['message'], file path to $data['filepath'], and file extension to $data['extension'].
If the file fails to upload, assign 2 to $data['success'] and 'File not uploaded.' to $data['message'].
Return the $data array in JSON format.
<?php namespace App\Controllers;
use App\Models\Users;
class UsersController extends BaseController{
public function index(){
return view('index');
}
public function fileUpload(){
$data = array();
// Read new token and assign to $data['token']
$data['token'] = csrf_hash();
## Validation
$validation = \Config\Services::validation();
$input = $validation->setRules([
'file' => 'uploaded[file]|max_size[file,1024]|ext_in[file,jpeg,jpg,docx,pdf],'
]);
if ($validation->withRequest($this->request)->run() == FALSE){
$data['success'] = 0;
$data['error'] = $validation->getError('file');// Error response
}else{
if($file = $this->request->getFile('file')) {
if ($file->isValid() && ! $file->hasMoved()) {
// Get file name and extension
$name = $file->getName();
$ext = $file->getClientExtension();
// Get random file name
$newName = $file->getRandomName();
// Store file in public/uploads/ folder
$file->move('../public/uploads', $newName);
// File path to display preview
$filepath = base_url()."/uploads/".$newName;
// Response
$data['success'] = 1;
$data['message'] = 'Uploaded Successfully!';
$data['filepath'] = $filepath;
$data['extension'] = $ext;
}else{
// Response
$data['success'] = 2;
$data['message'] = 'File not uploaded.';
}
}else{
// Response
$data['success'] = 2;
$data['message'] = 'File not uploaded.';
}
}
return $this->response->setJSON($data);
}
}
4. View – Create HTML form & Write AJAX code for file upload
- Create a file
index.phpin theapp/Views/folder. - Include a hidden element in the HTML file to store the CSRF token name obtained from the
.envfile. Assign the CSRF hash value to thevalueattribute.
<input type="hidden" class="txt_csrfname" name="<?= csrf_token() ?>" value="<?= csrf_hash() ?>" />
- Utilize jQuery to display the AJAX response message within the
<div id="responseMsg">element. - Using jQuery, create an
<img>and<a>element within the<div id="filepreview">to display a file preview based on the file extension. - Build a form with the method set to
postand the action attribute set to"<?=site_url('users/fileUpload')?>". Include an input element of type"file"and a button in the form. - Apply jQuery to display any validation errors in the
<div id="err_file">element if the file fails to pass validation.
jQuery Script –
- When the button is clicked, retrieve the CSRF Token name and hash from the hidden field and assign them to the variables
csrfNameandcsrfHash. - Check if a file has been selected. If not, display an alert message saying
"Please select a file." - If a file is selected, use the
FormDataobject to pass the selected file. Include the CSRF Token with theFormData. - Send an AJAX POST request to
"<?=site_url('users/fileUpload')?>", passing theFormDataobject as the data. - In the successful callback, update the CSRF Token by assigning
response.tokento.txt_csrfname. - If
response.successequals 1, it means the file was successfully uploaded. Display the response message and preview the file based on its extension. - If
response.successequals 2, it means the file was not uploaded. Display the response message. - If
response.successis neither 1 nor 2, it means the file did not pass validation. Display the error message.
<!DOCTYPE html>
<html>
<head>
<title>How to upload a file using jQuery AJAX in CodeIgniter 4</title>
<link rel="stylesheet" type="text/css" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<style type="text/css">
.displaynone{
display: none;
}
</style>
</head>
<body>
<div class="container">
<!-- CSRF token -->
<input type="hidden" class="txt_csrfname" name="<?= csrf_token() ?>" value="<?= csrf_hash() ?>" />
<div class="row">
<div class="col-md-12">
<!-- Response message -->
<div class="alert displaynone" id="responseMsg"></div>
<!-- File preview -->
<div id="filepreview" class="displaynone" >
<img src="" class="displaynone" with="200px" height="200px"><br>
<a href="#" class="displaynone" >Click Here..</a>
</div>
<!-- File upload form -->
<form method="post" action="<?=site_url('users/fileUpload')?>" enctype="multipart/form-data">
<div class="form-group">
<label for="file">File:</label>
<input type="file" class="form-control" id="file" name="file" />
<!-- Error -->
<div class='alert alert-danger mt-2 d-none' id="err_file"></div>
</div>
<input type="button" class="btn btn-success" id="submit" value="Upload">
</form>
</div>
</div>
</div>
<!-- Script -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$('#submit').click(function(){
// CSRF Hash
var csrfName = $('.txt_csrfname').attr('name'); // CSRF Token name
var csrfHash = $('.txt_csrfname').val(); // CSRF hash
// Get the selected file
var files = $('#file')[0].files;
if(files.length > 0){
var fd = new FormData();
// Append data
fd.append('file',files[0]);
fd.append([csrfName],csrfHash);
// Hide alert
$('#responseMsg').hide();
// AJAX request
$.ajax({
url: "<?=site_url('users/fileUpload')?>",
method: 'post',
data: fd,
contentType: false,
processData: false,
dataType: 'json',
success: function(response){
// Update CSRF hash
$('.txt_csrfname').val(response.token);
// Hide error container
$('#err_file').removeClass('d-block');
$('#err_file').addClass('d-none');
if(response.success == 1){ // Uploaded successfully
// Response message
$('#responseMsg').removeClass("alert-danger");
$('#responseMsg').addClass("alert-success");
$('#responseMsg').html(response.message);
$('#responseMsg').show();
// File preview
$('#filepreview').show();
$('#filepreview img,#filepreview a').hide();
if(response.extension == 'jpg' || response.extension == 'jpeg'){
$('#filepreview img').attr('src',response.filepath);
$('#filepreview img').show();
}else{
$('#filepreview a').attr('href',response.filepath).show();
$('#filepreview a').show();
}
}else if(response.success == 2){ // File not uploaded
// Response message
$('#responseMsg').removeClass("alert-success");
$('#responseMsg').addClass("alert-danger");
$('#responseMsg').html(response.message);
$('#responseMsg').show();
}else{
// Display Error
$('#err_file').text(response.error);
$('#err_file').removeClass('d-none');
$('#err_file').addClass('d-block');
}
},
error: function(response){
console.log("error : " + JSON.stringify(response) );
}
});
}else{
alert("Please select a file.");
}
});
});
</script>
</body>
</html>
5. Output
6. Conclusion
This article explains how to use jQuery AJAX and CodeIgniter 4 to upload files and display preview in web applications. With the combination of jQuery’s simplicity and CodeIgniter 4’s powerful features, you can create an efficient yet user-friendly file upload functionality according to your project needs.
Don’t hesitate to explore and enhance this process further.
If you found this tutorial helpful then don't forget to share.