Why do I hit error in AJAX file upload with jQuery? - php

I am working on a multiple file uploader using HTML5's FormData and jQuery. I have the following code:
$(function() {
$('#file').bind("change", function() {
var formData = new FormData();
//loop for add $_FILES["upload"+i] to formData
for (var i = 0, len = document.getElementById('file').files.length; i < len; i++) {
formData.append("file" + i, document.getElementById('file').files[i]);
}
//send formData to server-side
$.ajax({
url : "file-upload.php",
type : 'post',
data : formData,
dataType : 'json',
async : true,
processData: false, // tell jQuery not to process the data
contentType: false, // tell jQuery not to set contentType
error : function(request) {
alert('error!!');
console.log(request.responseText);
},
success : function(json) {
alert('success!!');
$('#upload-result')[0].append(json);
}
});
});
});
I can see that my file-upload.php works fine because the files are uploaded! But why does my jQuery hit the error function and not the success function? I get an alert of Error.
In the console window, I see the result of my PHP echo call! Which I want to append to #upload-result as shown in my success function.
PHP code
foreach($_FILES as $index => $file)
{
$fileName = $file['name'];
// echo '[ file name: ' . $fileName . ' - ';
$fileTempName = $file['tmp_name'];
// echo 'file temp name: ' . $fileTempName . ' ]';
if(!empty($file['error'][$index]))
{
// some error occured with the file in index $index
// yield an error here
return false; // return false also immediately perhaps??
}
// check whether it's not empty, and whether it indeed is an uploaded file
if(!empty($fileTempName) && is_uploaded_file($fileTempName))
{
// the path to the actual uploaded file is in $_FILES[ 'file' ][ 'tmp_name' ][ $index ]
// do something with it:
move_uploaded_file($fileTempName, "uploads/" . $fileName);
echo json_encode('<p>Click here to download file!</p>');
}
}

I figured it out. I was getting the jQuery AJAX error even though my status code was 200 for the php file because I had my dataType as JSON, whilst I was returning simple HTML.
dataType: 'html',
Fixed it!
Thanks all.

Related

Uploaded file not saving in the directory (PHP AJAX) "Serious in Need"

So i try this simple upload code but it doesn't work properly for me.
As cFos Speed shows the file uploading process is OK and 150kb pic is uploading, but at the end the file is not in the directory.
Also mkdir doesn't create a new folder. although i gave all permissions such az rwx chmod and apache:apache chown completely to the files i'm working on.
Here's the codes for html and ajax :
<input type="file" name="authform" id="authform" accept="image/png">
and
$(document).ready(function()
{
$("#authform").on("change", function()
{
var input = $(this);
var inputLength = input[0].files.length;
var file;
var formData = new FormData();
for (var i = 0; i < inputLength; i++)
{
file = input[0].files[i];
formData.append( 'authform[]', file);
};
$.ajax({
url: "file_upload.php",
type: "POST",
data: formData,
processData: false,
contentType: false,
});
and for the file_upload.php:
<?php
if (!file_exists('uploads')) {
mkdir('uploads', 0777);
}
$filename = time()."_".$_FILES['file']['name'];
if ( 0 < $_FILES['file']['error']) {
echo 'Error: ' . $_FILES['file']['error'] . '<br>';
}
else {
move_uploaded_file($_FILES['file']['tmp_name'], 'downloads/user-files/' . $filename);
}
echo 'downloads/user-files/'.$filename;
die;
?>
And Yes! i used a different directory because as said before mkdir does not work...
So what do you suggest guys?
Your file input does not have the multiple attribute so there is no need to loop through it as it will only have one file associated with it.
$("#authform").on("change", function()
{
var formData = new FormData();
formData.append('authform', this.files[0]);
$.ajax({
url: "file_upload.php",
type: "POST",
data: formData,
processData: false,
contentType: false
});
});
In your php code you refer to the file with the parameter file but you set it to authform in the js.
<?php
if (!file_exists('uploads')) {
mkdir('uploads', 0777);
}
$filename = time()."_".$_FILES['authform']['name'];
if ( 0 < $_FILES['file']['error']) {
echo 'Error: ' . $_FILES['authform']['error'] . '<br>';
}
else {
move_uploaded_file($_FILES['authform']['tmp_name'], 'downloads/user-files/' . $filename);
}
echo 'downloads/user-files/'.$filename;
die;
?>
The answer was I should have done this with copy() instead of move_uploaded_file().
I only needed a Form with enctype="multipart/form-data" and input with type="file", then with a submit action do this:
copy($_FILES['authform']['tmp_name'], "/var/www/html/test/app/downloads/user-files/" . $_FILES['authform']['name']);
And that's it! Works like a gem!

Parse CSV file to JSON after uploading using temporary copy

I'm almost finishing building a functionality for parsing CSV files to JSON and just need help in piecing it together. The way it works is that files will be uploaded using AJAX/Jquery. Once the files has been uploaded and sent the PHP to parse the CSV file to JSON will then execute.
After parsing, the converted file will be push or sent to the API as a JSON object. Here is the code that I have been working. For the uploading i'm using this plugin AJAX/JQuery File Uploader
This functionality is also built on using RactiveJS
AJAX/Jquery File Uploader
This is the section where I'm currently uploading or placing the file. URL is pointed at the upload.php.
<div id="fileuploader">Upload</div>
<script>
$(document).ready(function() {
$("#fileuploader").uploadFile({
url: 'upload.php',
});
})
</script>
Uploads.php
Is there a way to GET the temporary copy of the uploaded file and parse using the PHP code I have built below to convert the CSV to JSON
<?php
if ( 0 < $_FILES['file']['error'] ) {
echo 'Error' . $_FILES['file']['error'] . '<br/>';
}
else {
move_uploaded_file($_FILES['file']['tmp_name'], 'uploads/' . $_FILES['file']['name']);
}
?>
PHP (CSV to JSON)
Right now be the file is being declared manually.
<?php
$json_data = csvToJson('lms.csv');
?>
<?php
function csvToJson($fname) {
if (!($fp = fopen($fname, 'r') )) {
die("Can't open file");
}
else {
('Upload File');
}
$key = fgetcsv($fp, "1024", ",");
$json = array();
while ($row = fgetcsv($fp, "1024", ",")) {
$json[] = array_combine($key, $row);
}
fclose($fp);
foreach ( $json as $k=>$v ) {
$json[$k]['accountName'] = $json[$k]['ACCOUNT NAME'];
$json[$k]['dateRequested'] = $json[$k]['DATE'];
unset($json[$k]['ACCOUNT NAME']);
unset($json[$k]['DATE']);
}
return json_encode($json, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_NUMERIC_CHECK);
}
?>
<?php // $target_file = fopen($_FILES["fileToUpload"]["tmp_name"], 'r'); ?>
Send Converted to API (Ractive/AJAX/JS)
As you can see the sending part is triggered by an on-click event (app.on)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ractive/0.9.0-build-48/ractive.js"></script>
<script type="text/javascript">
var app = new Ractive({
el : '#container',
template : '#template',
});
var proxy = 'http://192.168.1.126/lms-dev-noel/proxy.php';
var endpoint = 'account/leads/';
var rt = 'POST';
var url = proxy+'?endpoint='+endpoint+'&rt='+rt;
var lms_json = <?php echo json_encode($json_data); ?>;
var jobjects = JSON.parse(lms_json);
for ( i = 0; i < jobjects.length; i++ ) {
var data = jobjects[i];
console.log(data);
$.ajax({
type : 'POST',
url : url,
data : data,
dataType : 'json',
success : function() {
},
error : function(error) {
console.log('Error')
}
});
}
</script>
Warning and Notices
Well, it depends a bit on where that csvToJson function is located in your code. If it's within uploads.php, or in a separate file that you can include in uploads.php, then you can just do:
move_uploaded_file($_FILES['file']['tmp_name'], 'uploads/' . $_FILES['file']['name']);
$json_data = csvToJson('uploads/' . $_FILES['file']['name']);
echo $json_data;
Then in the script, change
var lms_json = <?php echo json_encode($json_data); ?>;
to
var lms_json;
and move it to the top of your javascript.
It seems like you are trying to assign the variable before the API call has been made. Instead you need to capture the data from the the response of the uploadFile call (as per these docs: http://hayageek.com/docs/jquery-upload-file.php):
$("#fileuploader").uploadFile({
url: 'upload.php',
onSuccess:function(files,data,xhr,pd)
{
//data: response from server
lms_json = data;
}
});

How to access file from multipart/form-data [ PHP ]

I have a frontend of my application writen in angular which basicly pick the file and send backend file name and rest of the form information:
Frontend part looks like:
$scope.submit = function() {
if ($scope.file) {
$scope.upload($scope.file);
}
};
// upload on file select or drop
$scope.upload = function (file) {
Upload.upload({
url: 'sub.php',
data: {file: file, 'country': $scope.submodelCountry}
}).then(function (resp) {
console.log('Success ' + resp.config.data.file.name + ' uploaded. Response: ' + resp.data);
}, function (resp) {
console.log('Error status: ' + resp.status);
}, function (evt) {
var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
console.log('progress: ' + progressPercentage + '% ' + evt.config.data.file.name);
});
};
My backend is written in PHP:
I basicly access this 2 variabiles by:
$fileName = $_FILES['file']['name']; // value = fileName.csv
$country = $_POST['country']; // value = CZE
So looks my backend get all needed information however I am not able to fopen the file with $file = fopen($fileName,"r");
How can I access this file guys? Or how can I upload it on a server to use it after?
you have to upload the file to some folder, then you can access that,
Your file will be present in tmp directory, so
Use move_uploaded_files(), to move your file,
<?php
$uploads_dir = '/uploads';
if(move_uploaded_file($_FILES["file"]["tmp_name"],
"$uploads_dir/".$_FILES["file"]["file_name"])){
echo "file uploaded";
}
?>

PHP can't pick up file

I've been trying to create a registration form that requires students to upload documents at the very end. However, after picking up the form values via jQuery, the PHP document can't seem to pick up my uploaded form. Any ideas?
Form:
<form id="joinUs" enctype="multipart/form-data" method="post">
<!--various form fields-->
<input type="file" name="transcript" id="transcript">
<div class="button" id="submit">Submit!</div>
</form>
jQuery:
$("#submit").click(function(){
//firstName, lastName, grade, studentID, email, phone are all form values
var data = "firstName="+firstName+"&lastName="+lastName+"&grade="+grade+"&studentID="+studentID+"&email="+email+"&phone="+phone;
$.ajax({
type: "POST",
url: "join_submit.php",
data: data,
success: function() {
location.href="http://mvcsf.com/new/success.php";
}
});
join_submit.php
$allowedExtensions = array("pdf");
$max_filesize = 20000;
$upload_path = "docs/transcripts";
$filename = $_FILES["transcript"]["name"];
$filesize = $_FILES["transcript"]["size"];
$extension = $_FILES["transcript"]["type"];
if ($_FILES["transcript"]["error"] > 0) {
echo "Error: " . $_FILES["transcript"]["error"] . "<br />";
}
else if((in_array($extension, $allowedExtensions)) && ($filesize < $max_filesize)) {
move_uploaded_file($_FILES["transcript"]["tmp_name"], $upload_path . $filename);
}
I ran this, and I got no errors. I also tried to print out the file name, except nothing printed out.
This should do it for you :
$("#submit").click(function () {
var transcript = $("#transcript").val();
var data = "firstName=" + firstName + "&lastName=" + lastName + "&grade=" + grade + "&studentID=" + studentID + "&email=" + email + "&phone=" + phone;
var formData = new FormData();
formData.append("file", transcript);
formData.append("data", data);
$.ajax({
type: "POST",
url: "join_submit.php",
enctype: 'multipart/form-data',//optional
cache: false,
contentType: false,
processData: false,
data: {
file: file
data: data
},
success: function () {
location.href = "http://mvcsf.com/new/success.php";
}
});
});
Cheers
First, In your code, you are posting data with $.ajax({...}) and the data sent is
"firstName="+firstName+"&lastName="+lastName+"&grade="+grade+"&studentID="+studentID+"&email="+email+"&phone="+phone;
There is no transcript at all.
Secondly, and most important, you cannot post file with $.ajax({...}) like that, it will not working like that. As #Roy M J says, you should take a look at FormData (for recent browser only), or take a look on the web for an upload jQuery plugin (don't re-invent the whell, some good plugin already exists :))
Take a look here
You cannot send a file like you do the values of HTML elements. There are two methods to file upload, the one I've used successfully is the AJAX method using a third-party feature called 'AjaxUploader'.You can download it here via GitHub. Once you've done it, add the ajaxuploader.js file in your 'js' folder (or wherever you've put all of your script files), include the file in the HTML page where you've to use the uploader. Now, uploading is as simple as follows.
HTML:
<input type="file" name="transcriptUploader" id="transcriptUploader" value="Upload" />
jQuery (you need to have the jQuery file included in your page):
new AjaxUpload('transcriptUploader', {
action: "page_to_handle_upload.php", // You need to have either a separate PHP page to handle upload or a separate function. Link to either one of them here
name: 'file',
onSubmit: function(file, extension) {
// This function will execute once a user has submitted the uploaded file. You can use it to display a loader or a message that the file is being uploaded.
},
onComplete: function(file, response) {
// This function will execute once your file has been uploaded successfully.
var data = $.parseJSON(response); // Parsing the returning response from JSON.
if(data.error == 0)
{
// If the file uploaded successfully.
}
else if(data.error == "size"){
// If the response object sent 'size' as the error. It means the file size exceeds the size specified in the code.
}
else if(data.error == "type"){
// If the response object sent 'type' as the error. It means the file type is not of that specified in the code (in your case, pdf).
}
else{
// In case the file didn't upload successfully or the code didn't return a usual error code. It is still an error so you need to deal with it appropriately.
}
}
});
Your back-end PHP code that will be doing all the heavy lifting (uploading the file, checking extensions, moving it etc):
if(isset($_FILES)) // Checking if a file is posted.
{
if ($_FILES['file']['error'] == 0) //Checking if file array contain 0 as an error. It means AJAX had no error posting the file.
{
$response = array(); // Initializing a new array.
$allowedExts = array("pdf"); // Allowable file format.
$filename = stripslashes($_FILES['file']['name']); // Storing file name.
//$extension = strtolower(self::_getExtension($filename)); // Fetching file extension.
// Code block to extract file extension and storing it in a variable called $extraction.
$i = strrpos($str, ".");
if (!$i)
{
$extension = "";
}
$l = strlen($str) - $i;
$extension = strlower(substr($str, $i + 1, $l));
$size = $_FILES['file']['size']; // Storing file size (in bytes).
$fileNameAfterUpload = md5((time() + microtime())) . '.' . $extension; // Concatinating file name and extension.
$baseSystemPath = "/var/www/<your_folder_name>/uploaded_transcripts/" // Path on which the file will be uploaded. Need to be relative web path.
$maxSize = 10*10*1024; // Storing file size. Be advised the file size is in bytes, so this calculation means max file size will be 10 MB.
$webPath = "uploaded_transcripts/". $filename; // Creating web path by concatinating base web path (the folder in which you'd be uploading the pdf files to) with file name.
if (in_array($extension, $allowedExts)) // Checking if file contains allowabale extensions.
{
if($size <= $maxSize) // Checking if the size of file is less than and equal to the maximum allowable upload size.
{
$moved = move_uploaded_file($_FILES['file']['tmp_name'], $webPath); // Moving the file to the path specified in $webPath variable.
if($moved == true)
{
$response['error'] = 0; // If moved successfully, storing 0 in the response array.
$response['path'] = $webPath; // Storing web path as path in the response array.
$response['filename'] = $filename; // Storing file name in the response array.
}
else
{
$response['error'] = 'internal'; // If move isn't successfull, return 'internal' to AJAX.
}
}
else
{
$response['error'] = 'size'; // If file size is too small or large, return 'size' to AJAX.
}
}
else
{
$response['error'] = 'type'; // If file type is not that of defined, return 'type' to AJAX.
}
echo json_encode($response); // Returning the response in JSON format to AJAX.
}
}
Do let me know if you need further assistance.
P.S: Don't forget to mark it as an answer if it worked.

Extjs+PHP-File upload error- trying to decode an invalid JSON String:

I am working in extjs+PHP[yii framework]. i am working on file upload control. i have view code as-
Ext.define('Balaee.view.kp.dnycontent.Content',
{
extend:'Ext.form.Panel',
requires:[
'Balaee.view.kp.dnycontent.ContentView'
],
id:'ContentId',
alias:'widget.Content',
enctype : 'multipart/form-data',
title:'This day in a history',
items:[
{
xtype: 'fileuploadfield',
hideLabel: true,
emptyText: 'Select a file to upload...',
//inputType: 'file',
id: 'upfile',
name:'file',
width: 220
}],
buttons: [{
xtype : 'button',
fieldlabel:'upload',
action:'upload',
name:'upload',
text: 'Upload',
formBind:'true',
handler: function() {
var form = this.up('form').getForm();
if(form.isValid()){
form.submit({
url: 'index.php/QuestionBank/Qbpaper/getFile',
waitMsg: 'Uploading your photo...',
// uploadPath:'/app/model',
success: function(fp, o) {
Ext.Msg.alert('Success', 'Your photo "' + o.result.file + '" has been uploaded.');
}
});} } }]});
i had written above code to send file from extjs4. My server side is in PHP [Yii framework]. To server side i had written code to receive this file as-
public function actiongetFile()
{
$fileName = $_FILES['upfile']['name'];
$fileSize = $_FILES['upfile']['size'];
$fileType = $_FILES['upfile']['type'];
$fp = fopen($fileName, 'r');
$content = fread($fp, filesize($fileName));
$content = addslashes($content);
fclose($fp);
if(!get_magic_quotes_gpc()){
$fileName = addslashes($fileName);
}
But server side code is not working correctly. While sending file from extjs,its giving error as-"Ext.Error: You're trying to decode an invalid JSON String:
PHP notice
Undefined index: upfile "
So in php how to access file which is get send via extjs4. Please help me
name:'file'
THIS ^ is index of you file in array.
id is internal, but name is a label for submition.
Try it. Use:
$_FILES['file']['name']
instead of:
$_FILES['upfile']['name']

Categories