carga de archivos jQuery AJAX PHP

159

Quiero implementar una carga de archivo simple en mi página de intranet, con la configuración más pequeña posible.

Esta es mi parte HTML:

<input id="sortpicture" type="file" name="sortpic" />
<button id="upload">Upload</button>

y este es mi script JS jquery:

$("#upload").on("click", function() {
    var file_data = $("#sortpicture").prop("files")[0];   
    var form_data = new FormData();
    form_data.append("file", file_data);
    alert(form_data);
    $.ajax({
        url: "/uploads",
        dataType: 'script',
        cache: false,
        contentType: false,
        processData: false,
        data: form_data,                         
        type: 'post',
        success: function(){
            alert("works"); 
        }
    });
});

Hay una carpeta llamada "uploads" en el directorio raíz del sitio web, con permisos de cambio para "usuarios" y "IIS_users".

Cuando selecciono un archivo con el formulario de archivo y presiono el botón de carga, la primera alerta devuelve "[object FormData]". ¿No se llama a la segunda alerta y la carpeta "uploads" también está vacía?

¿Alguien puede ayudarme a descubrir qué está mal?

También el siguiente paso debería ser cambiar el nombre del archivo con un nombre generado por el lado del servidor. Quizás alguien también pueda darme una solución para esto.

usuario2355509
fuente
Lea esto primero: stackoverflow.com/questions/166221/…
Vincent Decaux el
Todo funciona para mí, ¿tal vez es tu código PHP?
Korikulum
no hay nada más "conectado" con este formulario. ¿Qué quieres decir con mi código php?
user2355509
Lo que quiero decir es que su código funciona, tal vez el problema esté en el código del lado del servidor.
Korikulum
¿Obtiene un código de error 500 al ejecutar el script AJAX? Eso indicaría que es un error del lado del servidor. Además: asegúrese de que durante la depuración, envíe la respuesta del archivo PHP a la consola. De esa manera, si su código PHP arroja un error, ya sabe lo que está sucediendo.
Diederik

Respuestas:

286

Necesita un script que se ejecute en el servidor para mover el archivo al directorio de cargas. El ajaxmétodo jQuery (que se ejecuta en el navegador) envía los datos del formulario al servidor, luego un script en el servidor maneja la carga. Aquí hay un ejemplo usando PHP.

Su HTML está bien, pero actualice su script JS jQuery para que se vea así:

$('#upload').on('click', function() {
    var file_data = $('#sortpicture').prop('files')[0];   
    var form_data = new FormData();                  
    form_data.append('file', file_data);
    alert(form_data);                             
    $.ajax({
        url: 'upload.php', // point to server-side PHP script 
        dataType: 'text',  // what to expect back from the PHP script, if anything
        cache: false,
        contentType: false,
        processData: false,
        data: form_data,                         
        type: 'post',
        success: function(php_script_response){
            alert(php_script_response); // display response from the PHP script, if any
        }
     });
});

Y ahora para el script del lado del servidor, usando PHP en este caso.

upload.php : un script PHP que se ejecuta en el servidor y dirige el archivo al directorio de cargas:

<?php

    if ( 0 < $_FILES['file']['error'] ) {
        echo 'Error: ' . $_FILES['file']['error'] . '<br>';
    }
    else {
        move_uploaded_file($_FILES['file']['tmp_name'], 'uploads/' . $_FILES['file']['name']);
    }

?>

Además, un par de cosas sobre el directorio de destino:

  1. Asegúrese de tener la ruta correcta del servidor , es decir, comenzando en la ubicación del script PHP, cuál es la ruta al directorio de carga, y
  2. Asegúrate de que se pueda escribir .

Y un poco sobre la función PHP move_uploaded_file, utilizada en el script upload.php :

move_uploaded_file(

    // this is where the file is temporarily stored on the server when uploaded
    // do not change this
    $_FILES['file']['tmp_name'],

    // this is where you want to put the file and what you want to name it
    // in this case we are putting in a directory called "uploads"
    // and giving it the original filename
    'uploads/' . $_FILES['file']['name']
);

$_FILES['file']['name']es el nombre del archivo a medida que se carga. No tienes que usar eso. Puede darle al archivo cualquier nombre (compatible con el sistema de archivos del servidor) que desee:

move_uploaded_file(
    $_FILES['file']['tmp_name'],
    'uploads/my_new_filename.whatever'
);

Y finalmente, tenga en cuenta sus valores de configuración upload_max_filesizeY de PHP post_max_size, y asegúrese de que sus archivos de prueba no excedan tampoco. Aquí hay ayuda para verificar la configuración de PHP y cómo establecer el tamaño máximo de archivo y la configuración de publicación .

Nudillos sangrientos
fuente
hey BloodyKnuckles! gracias, creo que esto fue una gran cosa, entendí mal. Así que agregué el archivo php, y ahora estoy un poco más cerca. ¡La segunda alerta también aparece! pero la carpeta aún está vacía.
user2355509
Ah, el nombre de entrada de formulario "sortpic" se cambia a "archivo" en la form_data.appendfunción. Así que cambié el script PHP para reflejar el nuevo nombre de entrada del formulario. También incluí la respuesta del script PHP en la alerta de éxito de ajax para ayudar con la depuración.
bloodyKnuckles
1
Amigo, me da un archivo de índice indefinido de error en$_FILES['file']
Hendry Tanaka
1
@partho, el código prop ('archivos') [0] accede al archivo local destinado a la carga al servidor. Si necesita más explicación, busque la función jQuery "prop" y "carga de archivos html5".
bloodyKnuckles
1
Resolví este problema, porque el tamaño del archivo era demasiado grande.
Ron Tornambe
4
**1. index.php**
<body>
    <span id="msg" style="color:red"></span><br/>
    <input type="file" id="photo"><br/>
  <script type="text/javascript" src="jquery-3.2.1.min.js"></script>
  <script type="text/javascript">
    $(document).ready(function(){
      $(document).on('change','#photo',function(){
        var property = document.getElementById('photo').files[0];
        var image_name = property.name;
        var image_extension = image_name.split('.').pop().toLowerCase();

        if(jQuery.inArray(image_extension,['gif','jpg','jpeg','']) == -1){
          alert("Invalid image file");
        }

        var form_data = new FormData();
        form_data.append("file",property);
        $.ajax({
          url:'upload.php',
          method:'POST',
          data:form_data,
          contentType:false,
          cache:false,
          processData:false,
          beforeSend:function(){
            $('#msg').html('Loading......');
          },
          success:function(data){
            console.log(data);
            $('#msg').html(data);
          }
        });
      });
    });
  </script>
</body>

**2.upload.php**
<?php
if($_FILES['file']['name'] != ''){
    $test = explode('.', $_FILES['file']['name']);
    $extension = end($test);    
    $name = rand(100,999).'.'.$extension;

    $location = 'uploads/'.$name;
    move_uploaded_file($_FILES['file']['tmp_name'], $location);

    echo '<img src="'.$location.'" height="100" width="100" />';
}
Hasib Kamal
fuente
2
var formData = new FormData($("#YOUR_FORM_ID")[0]);
$.ajax({
    url: "upload.php",
    type: "POST",
    data : formData,
    processData: false,
    contentType: false,
    beforeSend: function() {

    },
    success: function(data){




    },
    error: function(xhr, ajaxOptions, thrownError) {
       console.log(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
    }
});
Azhar
fuente
0

y este es el archivo php para recibir los archivos subidos

<?
$data = array();
    //check with your logic
    if (isset($_FILES)) {
        $error = false;
        $files = array();

        $uploaddir = $target_dir;
        foreach ($_FILES as $file) {
            if (move_uploaded_file($file['tmp_name'], $uploaddir . basename( $file['name']))) {
                $files[] = $uploaddir . $file['name'];
            } else {
                $error = true;
            }
        }
        $data = ($error) ? array('error' => 'There was an error uploading your files') : array('files' => $files);
    } else {
        $data = array('success' => 'NO FILES ARE SENT','formData' => $_REQUEST);
    }

    echo json_encode($data);
?>
kavehmb
fuente
Que esta if (true)haciendo Siempre se evalúa como verdadero, por lo que es inútil, ¿no? También tienes un extremo final rizado.
Mr.Web
Te lo arreglé. :)
Mr.Web
0

Usa js puro

async function saveFile() 
{
    let formData = new FormData();           
    formData.append("file", sortpicture.files[0]);
    await fetch('/uploads', {method: "POST", body: formData});    
    alert('works');
}
<input id="sortpicture" type="file" name="sortpic" />
<button id="upload" onclick="saveFile()">Upload</button>
<br>Before click upload look on chrome>console>network (in this snipped we will see 404)

El nombre de archivo se incluye automáticamente para solicitarlo y el servidor puede leerlo, el 'tipo de contenido' se establece automáticamente en 'multiparte / datos de formulario'. Aquí hay un ejemplo más desarrollado con manejo de errores y envío adicional de json

Kamil Kiełczewski
fuente
-1

Mejor carga de archivos usando Jquery Ajax con Materialise Haga clic aquí para descargar

Cuando selecciona la imagen, la imagen se convertirá en la base 64 y puede almacenarla en la base de datos para que también sea liviana.

Sheth Urshit
fuente