-1

(Note: Updated title to better match the question)

I am working on adding an image upload feature to ajax chat, and I have the HTML and PHP already written (basically copied from W3Schools) to do this. I have a test HTML page set up on the server to test the image uploads and that works just fine - the form works and the file is uploaded when the "Upload Image" button is pressed (to execute the PHP upload code). However, once the upload is complete the page switches to a blank page with the URL for my upload.php file.

I am currently using a modal in HTML to initially hide the image upload form and only appear when the "Image" button in the chat is pressed. The code is very simple, and as I said is basically the same as seen in the above link but placed inside a modal.

And before anyone complains, I know PHP is easy to exploit and can be dangerous when put on a website but this has been determined to be a non-issue in my case.

Below is the code for the image upload modal. Please pardon all the in-line CSS, I will eventually move it to its own stylesheet but have been using in-line for development purposes. Note that display is set to block for debugging. For the live site it would be set to none and a javascript function is used to set it to block when the "Image" button is pressed in the chat module.

<html>
    <body>
        <div id="imageUploadModal" style="display:block; position:fixed; z-index:1; left:0; top:0; width:100%; height:100%;.
             overflow:auto; background-color:rgb(0,0,0); background-color:rgba(0,0,0,0.4);">
            <div style="background-color:#fefefe; margin:15% auto; padding:20px; border:1px solid #888; width:80%;">
                <span style="color:#aaa; float:right; font-size:28px; font-weight:bold;">&times;</span>
                <form action="upload.php" method="post" enctype="multipart/form-data">
                    Select image:
                    <input type="file" name="fileToUpload" id="fileToUpload"/>
                    <input type="submit" value="Upload Image" name="submit"/>
                </form>
            </div>
        </div>
    </body>
</html>

UPDATE: Below are the contents of upload.php:

<?php
// Error reporting
error_reporting(E_ALL);
ini_set('display_errors', 1);
$target_dir = "uploads/";
$target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
$uploadOk = 1;
$imageFileType = pathinfo($target_file,PATHINFO_EXTENSION);
// Check if image file is an actual image
if(isset($_POST["submit"])) {
    $check = getimagesize($_FILES["fileToUpload"]["tmp_name"]);
    if($check !== false) {
        //The file is an image
        $uploadOk = 1;
    } else {
        //The file is not an image
        $uploadOk = 0;
    }
}

// Check if file already exists
if (file_exists($target_file)) {
    //The file already exists
    $uploadOk = 0;
}

// Check file size
if (2000000 < $_FILES["fileToUpload"]["size"]) {
    //The file is too large
    $uploadOk = 0;
}

// Allow certain file formats
if (($imageFileType != "jpg") && ($imageFileType != "png")
    && ($imageFileType != "jpeg") && ($imageFileType != "gif")) {
    //Only JPG, JPEG, PNG, and GIF files are allowed
    $uploadOk = 0;
}

// Check if $uploadOk is set to 0 by an error
if ($uploadOk == 0) {
    //The file was not uploaded
    exit();
// if everything is ok, try to upload the file
} else {
    if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) {
        exit();
    } else {
        //There was an error uploading the file
        exit();
    }
}
?>

EDIT: Updated HTML/Javascript

// Ajax image upload
$(document).ready(function() {
    $("#uploadForm").submit(function(event) {
        event.preventDefault();

        var $form = $("#uploadForm");
        var serializedData = $form.serialize();

        var request = $.ajax({
            type: "POST",
            url: "/upload.php",
            data: serializedData
        });

        request.done(function() {
            console.log("AJAX Success!");
            closeImageUploadModal();
        });
    })
});

HTML:

<div id="imageUploadModal" style="display:none; position:fixed; z-index:1; left:0; top:0; width:100%; height:100%; 
    overflow:auto; background-color:rgb(0,0,0); background-color:rgba(0,0,0,0.4);">
    <div style="background-color:#0e0e0e; color:#aaa;  margin:15% auto; padding:20px; border:1px solid #888; width:50%;">
        <span id="close" style="color:#aaa; float:right; font-size:28px; font-weight:bold;" onclick="closeImageUploadModal()">&times;</span>
        <form id="uploadForm">
            <h3><b>Select image:</b></h3>
            <input type="file" name="fileToUpload" id="fileToUpload" accept=".jpg, .JPG, .png, .PNG, .jpeg, .JPEG, .gif, .GIF"/>
            <input type="submit" value="Upload Image" name="submit"/>
        </form>
    </div>
</div>
DerStrom8
  • 1,311
  • 2
  • 23
  • 45
  • Please show us the code for the chat application, especially the submit file event handler – frozen Jul 08 '17 at 18:27
  • I added the modal code. I can't show any more, unfortunately, due to some privacy issues – DerStrom8 Jul 08 '17 at 18:32
  • I added an update that may be useful in diagnosing the issue. – DerStrom8 Jul 08 '17 at 20:05
  • No ideas, even after the edits? Basically I want the PHP code located in upload.php to run without exiting the original page from which the PHP was called. I'm also adding the contents of upload.php to the question. – DerStrom8 Jul 09 '17 at 21:07
  • @randnum-1 Ignore the part about ajax chat (I'm about to remove it from the question). I figured out why the chat was closing and it was due to some custom code. I disabled the custom code and it no longer closes the chat, but it still brings up a blank page. – DerStrom8 Jul 10 '17 at 21:43
  • Your `upload.php` does not seem to return anything ever, so how is your AJAX part even supposed to check whether the upload was successful or not? _“but it still brings up a blank page”_ - if the URL changes after an AJAX request, then you must either have triggered that yourself in your code, or you did not prevent the normal form submit action properly. – CBroe Jul 12 '17 at 11:35
  • I did not call the PHP using AJAX, I called it from the HTML within the AJAX chat module – DerStrom8 Jul 12 '17 at 13:44
  • Ermmm... what are you expecting to happen, the upload script should probably redirect to another page or display something. Currently all routes lead to `exit();` which without a parameter - just stops - with a blank page! – Nigel Ren Jul 14 '17 at 06:04
  • The "exit()" was placed as part of some experimentation. Since this is being called from within an AJAX chat module, I *expect* the file to upload without leaving the chat page. Lars' answer suggests using AJAX to upload the image, and I am completely on board with that as it seems to make the most sense – DerStrom8 Jul 14 '17 at 10:55

2 Answers2

1

How to upload a file without refreshing or redirecting.

Method 1: Plugins

Plugins would probably be the best for you, since they are usually well tested and relatively bug free and require hardly any work to get it running. There are a number of plugins you can use, I have them listed below.

jQuery File Uploader

Multiple File Upload Plugin

Mini Multiple File Upload

jQuery File Upload


Method 2: Other StackOverflow Answers

There has been plenty of answers for this type of problem. I have listed some below.

How can I upload files asynchronously?

jQuery AJAX file upload PHP

How to use $.ajax() for input field text AND FILE upload?

jQuery Ajax File Upload

File Upload Ajax PHP


Additional Sources to look at

https://www.sanwebe.com/2012/06/ajax-file-upload-with-php-and-jquery

https://www.formget.com/ajax-image-upload-php/

If you need more sources to look at try searching:

How to upload file with AJAX and PHP

Uploading File with AJAX and PHP

Sending File to AJAX and PHP upload

File Upload AJAX and PHP


Solution

HTML

<form enctype="multipart/form-data">
    <input name="file" type="file" />
    <input type="button" value="Upload" onclick="UploadFile()" />
</form>

<progress></progress>

JavaScript and AJAX

Note: You will need jQuery for this section. Please link the lastest CDN to your document.

function UploadFile()
{
    $.ajax({
        url: 'upload.php',
        type: 'POST',

        data: new FormData($('form')[0]),

        cache: false,
        contentType: false,
        processData: false,

        xhr: function() {
            var myXhr = $.ajaxSettings.xhr();

            if (myXhr.upload)
            {
                myXhr.upload.addEventListener('progress', function(e)
                {
                    if (e.lengthComputable)
                    {
                        $('progress').attr({
                            value: e.loaded,
                            max: e.total,
                        });
                    }
                }, false);
            }

            return myXhr;
        },

        success: function() {
                     // close modal here
                 }
    });
}

This does work since I have tested it. You will need to change your PHP a little.

Lars Peterson
  • 1,508
  • 1
  • 10
  • 27
  • The question may seem "misleading" because it evolved significantly over the course of testing and troubleshooting. It started off seeming like it was one problem but ended up being another. And by the way, I spent days googling the suggested phrases and didn't find what I was looking for – DerStrom8 Jul 12 '17 at 12:30
  • Did my answer help? And I didn't mean to come off as being rude, just trying to help. – Lars Peterson Jul 12 '17 at 12:32
  • I appreciate the answer (it's the first I got). I just implemented the code but it takes me to the front page of my website with the following appended to the URL: `/?fileToUpload=.png&submit="Upload+Image"` and the file wasn't uploaded. Also, do you have an extra semicolon? Are you sure there should there be a semicolon on the line second up from the bottom? – DerStrom8 Jul 12 '17 at 12:45
  • Yes, there should be a semicolon there. The page should not have reloaded , refreshed, or redirected you. Are you sure you removed the old code and replaced it with my answer. The POST variables sent over the URL will be accessed in your upload.php file, using $_POST['example']; – Lars Peterson Jul 12 '17 at 13:22
  • I copied your code precisely with the exception of replacing the log text within the callback function (changed it to "File uploaded"). I got a syntax error saying I'm missing a ')' and it's pointing to the second line up from the bottom. I cannot seem to find an unmatched parenthesis though.... – DerStrom8 Jul 12 '17 at 13:52
  • I believe I know what the problem is. Do you have jQuery linked to the HTML document? `` – Lars Peterson Jul 12 '17 at 14:39
  • I wrote that code in Javascript code using a framework called jQuery. Not having the CDN linked to your document would render my code useless. – Lars Peterson Jul 12 '17 at 14:41
  • My page already uses jQuery so I already have this link. The URL and numbers are a bit different though, presumably an older version: `` – DerStrom8 Jul 12 '17 at 14:45
  • I tried changing the jquery link but it did not seem to have an effect. I also ran this function through JSLint and it said to use double quotes instead of single quotes (around `myform`, which I changed to match the id of my actual form). It also seemed to think I'm missing a `)` though I can't for the life of me figure out where. – DerStrom8 Jul 12 '17 at 14:57
  • Apologies for three comments in a row, but 1) You misspelled "function", 2) JSLint still seems to think it's missing a ')', and it's saying `Unexpected 'this'`on the line `$form = $(this)` – DerStrom8 Jul 12 '17 at 23:33
  • Thanks for the edit, now I am no longer getting the `Unexpected 'this'` error, but all of the tools I'm using to check syntax suggest the semicolon I mentioned earlier shouldn't be there. Additionally, whether it's there or not, I'm still kicked back to my homepage with the appended text in the URL I mentioned previously, and the file does not upload. – DerStrom8 Jul 14 '17 at 01:38
  • When I get home from work tonight I will figure this out and edit my answer. Sorry for my mistakes, I will be sure to test the code before I answer. – Lars Peterson Jul 14 '17 at 07:20
  • I've made progress! I added `function()` just inside the `$(document).ready()` and now I get the message "Hooray, it worked!" in the Chrome console. The file is still not being uploaded though, which suggests the call to upload.php isn't working correctly. – DerStrom8 Jul 14 '17 at 11:56
  • I just received a notification that the bounty will expire in a few days. Have you been able to determine why the file isn't uploaded with my latest code? I would really like to award you with the bounty because you've gotten me closer than anyone else but I'd like to get the upload working first. – DerStrom8 Jul 16 '17 at 12:49
  • I sincerely apologize, I completely forgot to work on this problem. I will work on it during work today and give you an answer within a couple of hours from now. – Lars Peterson Jul 17 '17 at 06:51
  • No such luck with the edit - the progress bar immediately fills up and the file doesn't get uploaded. Also, "fileToUpload" is the name of the file input element in the HTML. My old PHP gets its filename from the filename of the original image – DerStrom8 Jul 17 '17 at 11:44
  • I was able to get the file to upload by using your Javascript with my HTML and PHP but it still bumps me to the same page as before after the upload. I suspect that means there's a problem with my PHP? – DerStrom8 Jul 17 '17 at 11:51
  • I thought you wanted to stay on that page? What page would you like to go to after the upload? – Lars Peterson Jul 17 '17 at 11:58
  • I suppose I didn't word that properly. I meant that a while ago I mentioned that after the upload it would bump me back to the homepage with some values appended to the URL. It's doing that again. As I mentioned I *am* still using my PHP because yours did not seem to work as-is and I am not well versed in PHP so I was unable to find a fault. I got the upload to work but it still bumps me to a different page. The page is `http:///?fileToUpload=.png` – DerStrom8 Jul 17 '17 at 12:01
  • Just to clarify so I completely understand, the upload is working but it keeps you on the upload page with values appended to the URL? And you want to stay on the upload page but with no values on the URL? – Lars Peterson Jul 17 '17 at 12:05
  • Remember I am uploading from within an ajax chat module. When I upload it bumps me from the chat and takes me to the website home page (default page) with values appended to the URL. I want to stay inside the chat after the upload – DerStrom8 Jul 17 '17 at 12:08
  • I understand now, that means you either have a redirection in your PHP or try removing the `` with `` like I had in my HTML. When you have the `type="submit"` it automatically redirects or refreshes the page. – Lars Peterson Jul 17 '17 at 12:11
  • BINGO! Please note that the PHP you offered does not work (may want to note that in your answer) but with your Javascript and my PHP/HTML (with the exception of changing `type=submit` to `type=button` and adding an onclick listener) it now works! Many many thanks! – DerStrom8 Jul 17 '17 at 12:26
  • By the way, where would I put the code to close the modal after the upload is complete? I'd need some sort of callback, no? – DerStrom8 Jul 17 '17 at 12:36
  • 1
    THANK GOD! I was completely running out of ideas. I'm glad I could help. I have edited my answer to include where I think the code to close your modal should go. – Lars Peterson Jul 17 '17 at 12:55
  • Hmm, that seems to close it before the progress bar is finished – DerStrom8 Jul 17 '17 at 13:05
  • Scratch that, the upload is just happening faster than the progress bar updates :P – DerStrom8 Jul 17 '17 at 13:07
  • I'm pretty sure you were right the first time. I think it closes the modal before the download finishes. It does this because the success callback on the AJAX request gets called when the AJAX request is finished, not when the download finishes. So the download will still run in the background. I guess you can detect when the progress bar is full with JavaScript and then close the modal. That might be the best way. – Lars Peterson Jul 17 '17 at 13:13
  • The way I tested it was I uploaded a large image (12MB) and saw that it continued to update as the file was trying to upload, and didn't close until the progress bar completed – DerStrom8 Jul 17 '17 at 13:29
  • It looks pretty good to me =) Thanks again for all your help, you really earned the bounty with this one. – DerStrom8 Jul 17 '17 at 13:34
  • It was more of a team effort ;) Thanks for the bounty. – Lars Peterson Jul 17 '17 at 13:35
-1

Just merge your PHP code and HTML to a file and then, in the form, submit to it self.


    <?php
    $Fname = $_POST["Fname"];
    $Lname = $_POST["Lname"];
    ?>
    <html>
    <head>
    <title>Personal INFO</title>
    </head>
    <body>
    <form method="post" action="<?php echo $PHP_SELF;?>">
    First Name:<input type="text" size="12" maxlength="12" name="Fname"><br />
    Last Name:<input type="text" size="12" maxlength="36" name="Lname"><br />
    </form>
    <?
    echo "Hello, ".$Fname." ".$Lname.".<br />";
    ?>