SitePoint Sponsor

User Tag List

Results 1 to 16 of 16

Hybrid View

  1. #1
    SitePoint Member
    Join Date
    Sep 2012
    Posts
    24
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    AJAX responseText issue? (Dealing with creating an AJAX/PHP Upload an image code

    Hello!
    I have been working on making a form that uploads an image through ajax with php doing the upload. For some background I am having an issue where the xhr.readyState and .Status seem to run and upload.php seems to run (in safari it goes and runs upload.php it seems to me... I have not used the ajax/javascript debugger too much) but it will run my else statement (i believe becuase it goes to status 2 and then 4) and then run xhr.responseText. Unfortunately it does not seem to run the upload.php right (which may be a php problem). I went ahead and replaced the php with a print statement which when running alert(xhr.response.Text) comes up with a blank alert statement and I am at a loss where the issue is. Below is my form code, ajax code and the php code i'm trying to get a response from.

    Does anyone see the issue I am having? I am new to AJAX and have not worked with PHP in some time. I am working on upping my ajax/javascript skills but from my view it does not seem to be getting the ajax correctly.


    HTML CODE
    Code:
    <form action="scripts/upload.php" method="post" enctype="multipart/form-data">
    	    <label>Select a File to Upload</label> <input id="upload_file" type="file" name="upload_file" /> 
    	    <input type="button" onclick="loadFile()" value="Upload"  />
    	</form>
    JAVASCRIPT/AJAX CODE
    Code:
    //LOAD IMAGES THROUGH JAVASCRIPT WINDOW.ONLOAD = INIT();
    
    $(document).ready(function() {
      // Handler for .ready() called.
    
      $('.heading').click(function() {
    	  if($(this).find('li').is(':visible')) {	
    	  	$(this).find('li').slideUp('slow');	
      	}else {
      	  $('.heading').find('li').slideUp('slow');
    	  $(this).find('li').slideDown('slow');	
      	}
      })
    });
    
    var xhr = createRequest();
    
    function loadFile() {
    //retrieve the FileList object from the referenced element ID
    	var myFileList = document.getElementById('upload_file').files;
    	
    	//grab the first file object from the filelist
    	var myFile = myFileList[0];
    	
    	//set some variables containing attributes of file
    	var myFileName = myFile.name;
    	var myFileSize = myFile.size;
    	var myFileType = myFile.type;
    	
    	//alert the information gathered and if it is right
    	alert("FileName: " + myFileName + "- FileSize: " + myFileSize + " - FileType: " + myFileType);
    	
    	//check above by alert if file size is below a certain MB and of image type JPEG, PNG, GIF
    	
    	//Let's upload the complete file object
    	uploadFile(myFile);
    }
    
    function uploadFile(myFileObject) {
    	// Open Our formData Object
    	var formData = new FormData();
     
    	// Append our file to the formData object
    	// Notice the first argument "file" and keep it in mind
    	formData.append('my_uploaded_file', myFileObject);
     
    	// Create our XMLHttpRequest Object
    	xhr.onreadystatechange = addImage;
    	
    	// Open our connection using the POST method
    	xhr.open("POST", 'upload.php');
    	//Send the proper header information along with the request
    	xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    	
    	// Send the file
    	xhr.send(formData);
    }
    
    function addImage() {
    	if (xhr.readyState === 4 && xhr.status === 200) {
            alert("WIN");
            alert(xhr.responseText);
        } else {
    	    alert("ERROR ERROR: " + xhr.status);
        }
    }
    PHP
    PHP Code:
    <?php
        
    print("HELLO");
    ?>

    <?php
    /*
    define("UPLOAD_DIR", "../images");

    if (!empty($_FILES["myFile"])) {
        $myFile = $_FILES["myFile"];

        if ($myFile["error"] !== UPLOAD_ERR_OK) {
            echo "<p>An error occurred.</p>";
            exit;
        }

        // ensure a safe filename
        $name = preg_replace("/[^A-Z0-9._-]/i", "_", $myFile["name"]);

        // don't overwrite an existing file
        $i = 0;
        $parts = pathinfo($name);
        while (file_exists(UPLOAD_DIR . $name)) {
            $i++;
            $name = $parts["filename"] . "-" . $i . "." . $parts["extension"];
        }

        // preserve file from temporary directory
        $success = move_uploaded_file($myFile["tmp_name"],
            UPLOAD_DIR . $name);
        if (!$success) { 
            echo "<p>Unable to save file.</p>";
            exit;
        }

        // set proper permissions on the new file
        chmod(UPLOAD_DIR . $name, 0644);
    }
    */
    ?>
    I pasted all my PHP code although right now i'm just working with the print PHP code to get a response, I am sure there are many things (besides security checking) with my upload php code. Any help with where the issue is to get this image upload situation working would be great as then I can work on my DRAG & DROP API

  2. #2
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    6,056
    Mentioned
    219 Post(s)
    Tagged
    12 Thread(s)
    Hi there,

    the problem is this line:

    Code JavaScript:
    var xhr = createRequest();

    createRequest() is not defined, so by the time you get here:

    Code JavaScript:
    xhr.onreadystatechange = addImage;

    the variable xhr is undefined and your script falls over and dies.

    Also, please note that you will never see any output from the PHP script, as it is being called via AJAX.
    This is not the same as navigating to the page in your browser.

  3. #3
    SitePoint Member
    Join Date
    Sep 2012
    Posts
    24
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    my apologies. I forgot to past a function from another javascript file.

    Code:
    function createRequest() {
      try {
        request = new XMLHttpRequest();
      } catch (tryMS) {
        try {
          request = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (otherMS) {
          try {
            request = new ActiveXObject("Microsoft.XMLHTTP");
          } catch (failed) {
            request = null;
          }
        }
      }	
      return request;
    }
    This should define the javascript variable and add the correct Request depending upon browser (although event is not added to it), if i understand correctly?
    Is there any way to see output from your script? I understand that it doesn't navigate to another page but I thought it still could return the succes/failures of the script to responseText? I may have to go back to responseText and re-read it.

    With this new information is my ajax working correctly (besides a few cross browser issues I believe)?

  4. #4
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    6,056
    Mentioned
    219 Post(s)
    Tagged
    12 Thread(s)
    Hi,

    Once I added the missing function, your script worked for me.

    You might however want to change this:

    Code JavaScript:
    if (xhr.readyState === 4 && xhr.status === 200) {
      alert("WIN");
      alert(xhr.responseText);
    } else {
      alert("ERROR ERROR: " + xhr.status);
    }

    to this:

    Code JavaScript:
    if (xhr.readyState === 4 && xhr.status === 200) {
      console.log(xhr.responseText);
    }

    You can then see the output in the console. You would find this in Chrome (for example) by pressing F12 and selecting the "Console".

    I spent quite a while trying to get your PHP script to work, but kept getting quite bogged down, so I adapted a script from StackOverflow and ported the whole thing to jQuery:

    HTML Code:
    <!DOCTYPE HTML>
    <html>
      <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>jQuery File Upload</title>
        <script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>
      </head>
    
      <body>
        <form enctype="multipart/form-data">
          <input name="file" type="file" />
          <input type="button" value="Upload" />
        </form>
        <progress></progress>
      
        <script>
          $(':file').change(function(){
            var file = this.files[0];
            name = file.name;
            size = file.size;
            type = file.type;
            //your validation
          });
          
          $(':button').click(function(){
            var formData = new FormData($('form')[0]);
            $.ajax({
              url: 'upload.php',  //server script to process data
              type: 'POST',
              xhr: function() {  // custom xhr
                myXhr = $.ajaxSettings.xhr();
                if(myXhr.upload){ // check if upload property exists
                  myXhr.upload.addEventListener('progress',progressHandlingFunction, false); // for handling the progress of the upload
                }
                return myXhr;
              },
              success: function(response){
                console.log(response);
              },
              data: formData,
              //Options to tell JQuery not to process data or worry about content-type
              cache: false,
              contentType: false,
              processData: false
            });
          })		
          
          function progressHandlingFunction(e){
            if(e.lengthComputable){
              $('progress').attr({value:e.loaded,max:e.total});
            }
          }
        </script>
      </body>
    </html>
    PHP Code:
    <?php 
    move_uploaded_file
    ($_FILES["file"]["tmp_name"], "uploads/" $_FILES["file"]["name"]);
    echo 
    "Stored in: " "uploads/" $_FILES["file"]["name"];
    ?>
    The script lets you select a file, then upon submission it will upload it to an "uploads" folder, which it expects to find in the same location as itself.
    Upon successful completion, it will log the location of the uploaded file to the console.

    I would encourage you to check out the StackOverflow article, as the full script includes more functionality, such as error handlers, which I have left out here for the sake of brevity.

    Hope this helps you.

  5. #5
    SitePoint Member
    Join Date
    Sep 2012
    Posts
    24
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Pullo View Post
    Hi,

    Once I added the missing function, your script worked for me.

    You might however want to change this:

    Code JavaScript:
    if (xhr.readyState === 4 && xhr.status === 200) {
      alert("WIN");
      alert(xhr.responseText);
    } else {
      alert("ERROR ERROR: " + xhr.status);
    }

    to this:

    Code JavaScript:
    if (xhr.readyState === 4 && xhr.status === 200) {
      console.log(xhr.responseText);
    }

    You can then see the output in the console. You would find this in Chrome (for example) by pressing F12 and selecting the "Console".

    I spent quite a while trying to get your PHP script to work, but kept getting quite bogged down, so I adapted a script from StackOverflow and ported the whole thing to jQuery:

    HTML Code:
    <!DOCTYPE HTML>
    <html>
      <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>jQuery File Upload</title>
        <script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>
      </head>
    
      <body>
        <form enctype="multipart/form-data">
          <input name="file" type="file" />
          <input type="button" value="Upload" />
        </form>
        <progress></progress>
      
        <script>
          $(':file').change(function(){
            var file = this.files[0];
            name = file.name;
            size = file.size;
            type = file.type;
            //your validation
          });
          
          $(':button').click(function(){
            var formData = new FormData($('form')[0]);
            $.ajax({
              url: 'upload.php',  //server script to process data
              type: 'POST',
              xhr: function() {  // custom xhr
                myXhr = $.ajaxSettings.xhr();
                if(myXhr.upload){ // check if upload property exists
                  myXhr.upload.addEventListener('progress',progressHandlingFunction, false); // for handling the progress of the upload
                }
                return myXhr;
              },
              success: function(response){
                console.log(response);
              },
              data: formData,
              //Options to tell JQuery not to process data or worry about content-type
              cache: false,
              contentType: false,
              processData: false
            });
          })		
          
          function progressHandlingFunction(e){
            if(e.lengthComputable){
              $('progress').attr({value:e.loaded,max:e.total});
            }
          }
        </script>
      </body>
    </html>
    PHP Code:
    <?php 
    move_uploaded_file
    ($_FILES["file"]["tmp_name"], "uploads/" $_FILES["file"]["name"]);
    echo 
    "Stored in: " "uploads/" $_FILES["file"]["name"];
    ?>
    The script lets you select a file, then upon submission it will upload it to an "uploads" folder, which it expects to find in the same location as itself.
    Upon successful completion, it will log the location of the uploaded file to the console.

    I would encourage you to check out the StackOverflow article, as the full script includes more functionality, such as error handlers, which I have left out here for the sake of brevity.

    Hope this helps you.
    Hello thanks for the reference! I will have to read it over in a bit later tonight when I sit down to finish this up. Yea, I will be changing my PHP around... I actually think i found a major problem about the directory i am choosing currently, haha.

    I am wondering why you chose to do error handling on the jQuery side rather than the server side? As well, why you wrote it in jQuery vs. pure Javascript? I am just curious about that.. obviously jQuery is more cross browser compatible and easier to use. I have some above in this example only because I don't know how to make it pure javascript and everything I turn up is jQuery. I need to re-read about traversing the JS DOM.

    I will probably adapt my PHP to your script if I can't figure it out but I do like that PHP is doing most of the work, incase javascript is disabled, with a little index.html changes it can still work without ajax/js. and I did realize my mistake. some previous Form data had the wrong action="" area. This made my upload.php not run correctly. I must have mixed up my local old copy vs. new copy. I now have responseText working correctly although I haven't worked on my PHP script yet in terms of progress/error correction.

    I will have to keep looking at it to make sure I get it done the right way, haha. Really in the end I want to get this part done as fast as possible, as I want the addImage function to go through and add all images to a list and then from there add Dragon and Drop API into a 500x500 div and even go further to allow drag deletes somehow.

  6. #6
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    6,056
    Mentioned
    219 Post(s)
    Tagged
    12 Thread(s)
    Quote Originally Posted by kmalik View Post
    I am wondering why you chose to do error handling on the jQuery side rather than the server side?
    Not "rather than", but "as well as".
    It makes your app more responsive for your users.

    Quote Originally Posted by kmalik View Post
    As well, why you wrote it in jQuery vs. pure Javascript? I am just curious about that..
    Well, I saw from your first post that you were using jQuery anyway and as jQuery irons out so many browser incompatibility problems for you, it seemed to be the logical choice.
    The only reason I can see for not using jQuery is the added dependency, yet considering that the current jQuery.min.js weighs in at 92kb, that didn't seem like a terrible trade off in this situation.

    Quote Originally Posted by kmalik View Post
    some previous Form data had the wrong action="" area.
    This only makes a difference if JavaScript is disabled.

    Quote Originally Posted by kmalik View Post
    Really in the end I want to get this part done as fast as possible, as I want the addImage function to go through and add all images to a list and then from there add Dragon and Drop API into a 500x500 div and even go further to allow drag deletes somehow.
    You might want to look at this for the drag and drop functionality: http://jqueryui.com/draggable/

    Good luck!

  7. #7
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    6,056
    Mentioned
    219 Post(s)
    Tagged
    12 Thread(s)
    Yeah, that's why I turned to jQuery, I couldn't get your code to work either.
    The PHP part was no problem, but I couldn't manage to reference anything in $_FILES once the upload had taken place when doing it in native JS.

  8. #8
    SitePoint Member
    Join Date
    Sep 2012
    Posts
    24
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Pullo View Post
    Yeah, that's why I turned to jQuery, I couldn't get your code to work either.
    The PHP part was no problem, but I couldn't manage to reference anything in $_FILES once the upload had taken place when doing it in native JS.
    I actually determined that I was referencing the wrong variable in js. When doing it with HTML and php my_uploaded_file is referenced for the file information. The form variable was wrong referencing upload_file. That was the issue. I also added on window load prevent form submission if JavaScript is enabled. This makes it load with and without JavaScript.

    Now I can finally go ahead and put the files in on the callback function and add a delete button etc haha

  9. #9
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    6,056
    Mentioned
    219 Post(s)
    Tagged
    12 Thread(s)
    Quote Originally Posted by kmalik View Post
    When doing it with HTML and php my_uploaded_file is referenced for the file information. The form variable was wrong referencing upload_file.
    Yeah I changed that in my script, but still couldn't get it to work.
    Would you mind posting your working code?

  10. #10
    SitePoint Member
    Join Date
    Sep 2012
    Posts
    24
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The PHP and Form code are here below:
    Everything works although there are a few drag and drop issues that I later implemented that I have to work thorugh. As far as Upload, Delete, progress bar etc. all works in terms of ajax/php.

    FORM:::

    Code:
    <form action="scripts/upload.php" method="post" enctype="multipart/form-data">
    		    <label>Select a File to Upload</label>
    		    <input id="upload_file" type="file" name="upload_file" /> 
    		    <input type="submit" value="Upload" id="inputSubmit" />
    		    <input type="button" value="Hover Image Over To Delete" id="DeleteDrag" />
    		</form>

    PHP:::


    PHP Code:
    <?php
    /*
    $baseFolder =  dirname(dirname(__FILE__));
    $imageFolder = $baseFolder . "/images/";
    /*$imagesFolder = $baseFolder . "/images/"*/
    /*define("UPLOAD_DIR", "../images");*/
    /*echo $baseFolder;
    echo "</br>";
    echo $imageFolder;*/

    $baseFolder =  dirname(dirname(__FILE__));
    $imageFolder $baseFolder "/images/";
    define("UPLOAD_DIR"$imageFolder);

    if (!empty(
    $_FILES["my_uploaded_file"])) {
        
    $myFile $_FILES["my_uploaded_file"];

        if (
    $myFile["error"] !== UPLOAD_ERR_OK) {
            echo 
    "<p>An error occurred.</p>";
            exit;
        };

        
        
    // ensure a safe filename
        
    $name preg_replace("/[^A-Z0-9._-]/i""_"$myFile["name"]);


        
    // don't overwrite an existing file
        
    $i 0;
        
    $parts pathinfo($name);
        while (
    file_exists(UPLOAD_DIR $name)) {
            
    $i++;
            
    $name $parts["filename"] . "-" $i "." $parts["extension"];
        }

        
    // preserve file from temporary directory
        
    $success move_uploaded_file($myFile["tmp_name"],
            
    UPLOAD_DIR $name);
        

        
    // set proper permissions on the new file
        
    chmod(UPLOAD_DIR $name0644);
        
        
    $dirhandler opendir(UPLOAD_DIR);
        
    //create handler to directory
        
        //read all the files from directory
        
    $nofiles=0;
        while (
    $file readdir($dirhandler)) {
            
    //if $file isn't this directory or its parent
            //echo "FILE SYSTEM: " . $file . "<br/>";
            //add to the $files array
            
    if ($file != '.' && $file != '..') {
                
    $nofiles++;
                
    $files[$nofiles]=$file;
            } 
    //end of if loop
        
    //end of while loop
        //json_encode($files);
        
    if (!$success) { 
            
    $nofiles++;
            
    $files[$nofiles] = "Unable to upload file";
            exit;
        } else {
            
    $nofiles++;
            
    $files[$nofiles] = "File Upload Successfully";
        }
        echo 
    json_encode($files);
    } else {
        
    $dirhandler opendir(UPLOAD_DIR);
        
    //create handler to directory
        
        //read all the files from directory
        
    $nofiles=0;
        while (
    $file readdir($dirhandler)) {
            
    //if $file isn't this directory or its parent
            //echo "FILE SYSTEM: " . $file . "<br/>";
            //add to the $files array
            
    if ($file != '.' && $file != '..') {
                
    $nofiles++;
                
    $files[$nofiles]=$file;
            } 
    //end of if loop
        
    //end of while loop
        //json_encode($files);
       
        
    echo json_encode($files);
    }

    ?>

  11. #11
    Gre aus'm Pott gold trophysilver trophybronze trophy
    Pullo's Avatar
    Join Date
    Jun 2007
    Location
    Germany
    Posts
    6,056
    Mentioned
    219 Post(s)
    Tagged
    12 Thread(s)
    Hey,

    Thanks for that, but what I was really after was the JavaScript code.
    Would you mind posting that, too?


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •