HTMLeando: para desarrolladores Web

Pregunta


¿Cómo subir archivos con Ajax? 

Responder esta pregunta por dudin el 2008-11-19
Estoy haciendo una aplicación web usando los frameworks Symfony y Prototype para PHP y Javascript respectivamente. Deseo hacer un uploader usando Ajax. ¿Existe algo ya implementado?

Respuestas

Thumb_up
Thumb_down

0%
0%
No es posible subir ficheros vía Ajax porque Javascript no tiene acceso a ningunos de los ficheros cuando se envía el formulario, o sea la información GET / POST se recopila a través de Javascript, el cual no tiene ninguna manera de acceder al contenido de los ficheros locales por razones de seguridad.

Sin embargo, puede utilizar AJAX para obtener información de estado en la subida de ficheros.
Pero no se desanime, se pueden subir ficheros a través del clásico formulario HTML dentro de un IFRAME oculto y la experiencia del usuario será excelente.
Supongamos que tenemos un módulo llamado "files" y que en el mismo tenemos una acción "edit" donde se requiere subir imágenes, con la condición de no recargar la página actual ("edit") y que además muestre una miniatura de la imagen subida.
<?php
/* actions.class.php */
class filesActions extends sfActions
{
 
 public function executeEdit()
 {
 $this->files = array();
 }
 
 public function handleErrorEdit()
  {   
  if ($this->getRequestParameter('file')) 
   	{
	  	$this->files = $this->getRequestParameter('file');	
   	} else 
   	{
   		$this->files =  array();
   	}
    return sfView::SUCCESS;
  }
 
 public function executeUpload()
 {  	    	
  $this->prepareUpload();
  if ($this->getRequest()->hasFiles())
    { 
      $this->file = $this->getRequest()->getFileName('file');
    /* Limitar el tamaño a un máximo, usando el plugin  sfThumbnail */  
	  $thumbnail = new sfThumbnail(500, 400);
	  $thumbnail->loadFile($this->getRequest()->getFilePath('file'));
	  $thumbnail->save(sfConfig::get('sf_upload_dir').'/'.$fileName);
 
	/* Crea una imágenes en miniaturas que se mostrarán para indicar que subió correctamente  */
	  $thumbnail = new sfThumbnail(75, 75);
	  $thumbnail->loadFile($this->getRequest()->getFilePath('file'));
	  $thumbnail->save(sfConfig::get('sf_upload_dir').'/th/'.$fileName);
      $this->isUploaded =true;
    }
 
 }
 
 public function handleErrorUpload()
  { 
  	  $this->prepareUpload();
  	  return sfView::SUCCESS;
  }
 
 protected function prepareUpload()
 {
  $this->isUploaded = false;
  sfConfig::set('sf_web_debug', false);
  $this->getResponse()->addJavascript('upload');
  $this->setLayout('simple');	
 }
 
}

El template editSuccess.php
<?php use_helper('Validation') ?> 
<div id="data-form"> 
<?php echo form_tag('files/edit', 'id=form') ?>
 
  <div id="iframe">
	<iframe src="<?php echo url_for('files/upload')?>" frameborder="0"  ></iframe>
  </div>
  <div id="images-uploaded">
  <?php foreach ($files as $k => $file): ?>
    <?php echo include_partial('thumbnail', array('file' => $file)) ?> 
   <?php endforeach; ?> 
  </div>
   <div id="submit"><?php echo submit_to(__('Enviar')); ?>    </div>
  </form>
</div>
Template general de la aplicación simple.php:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
</head>
<body>
<?php echo $sf_data->getRaw('sf_content') ?></div>
</body>
</html>
 
Parcial _thumbnail.php:
<div class="thumbnail" ><img  src="/uploads/th/<?php echo $file?>" alt="<?php echo $file ?>" width="75" />
 <?php echo input_hidden_tag('file[]',$file)  ?></div>
El template uploadSuccess.php:
<?php use_helper('Validation') ?>
 
  <?php if ($sf_request->hasError('file')): ?>
    <?php echo  javascript_tag("alert('" .$sf_request->getError('file')."');
    							errorUpload(". $sf_params->get('imgnum').")
                             ")
     ?> 
  <?php endif; ?>
 
 <?php if ($isUploaded): ?>
     <?php echo include_partial('thumbnail', array('file' => $file)) ?> 
     <?php echo javascript_tag("uploaded(". $sf_params->get('imgnum')."); ") ?>
 <?php else: ?>
 
   <?php echo form_tag('files/upload', 'multipart=true  name=iform') ?>
   <?php echo input_file_tag('file', 'onChange=upload()') ?>
   <?php echo input_hidden_tag('imgnum')  ?>
   </form>
 
  <?php endif; ?>
El fichero javascript upload.js:
/* upload.js */
function upload(){
	//  Oculta los iframe anteriores
	var par = window.parent.document;
	var iframes = $A(par.getElementsByTagName('iframe'));
    $(iframes.last()).addClassName('hidden');
	//Crea un nuevo iframe
	var new_iframe = par.createElement('iframe');
	new_iframe.src = iframes.last().src;
	new_iframe.frameBorder = '0';
	par.getElementById('iframe').appendChild(new_iframe);
 
	// Pone una imagen de espera
	var images = getByIdParent('images-uploaded');
	var html_images = '<img src="/images/icons/loading.gif" border="0" />'
	var new_div = par.createElement('div');
	new_div.className = 'load';
	new_div.innerHTML = html_images;
	images.appendChild(new_div); 
 
 
	// Enviar
	var imgnum = images.getElementsByTagName('div').length - 1;
	document.iform.imgnum.value = imgnum;
	setTimeout(function(){document.iform.submit()}, 5000);
}
 
/**
 * Se llama luego que se ha subido el fichero al servidor
 *  */
function uploaded(id){
	var images = getByIdParent('images-uploaded');
	var imgdiv = images.getElementsByTagName('div')[id];
	imgdiv.innerHTML = $('thumbnail').innerHTML;
}
 
function errorUpload(id){
	var images = getByIdParent('images-uploaded');
	images.removeChild(images.getElementsByTagName('div')[id]);
}
 
function getByIdParent(id) 
{
	var par = window.parent.document;
	return par.getElementById(id);
 
}
Finalmente un poco de estilo mediante edit.css:
iframe {
	border-width: 0px;
	height: 90px;
	width: 300px;
	overflow:hidden;
	margin-left: 220px;
 
}
iframe.hidden {
	visibility: hidden;
	width:0px;
	height:0px;
}
 
#images-uploaded {
	width: 390px;
	margin:  0 10px;
}
 
#images-uploaded div {
	margin:  0  0 0 10px;
	width: 100px;
	height: 90px;
	border-style: solid;
	border-width: 5px;
	border-color: #DEDFDE;
	float: left;
	overflow: hidden;
	padding:4px;
}
 
#images-uploaded div:hover {
	border-color: #529EBD;
}
 

por maikel el 2008-11-21

Thumb_up
Thumb_down

0%
0%
Hola, se puede ver este ejemplo en funcionamiento. Gracias!
por Anónimo el 2009-01-26

Thumb_up
Thumb_down

0%
0%
no me funciona me sale error en clas filesactions alguna rason si me ayudan por favor
por Anónimo el 2009-05-22

Anónimo:   Entrar


Consejo: Sé tan específico y descriptivo como puedas. Comparte tu experiencia personal o tus conocimientos.
Puedes investigar para completar tu respuesta.

Puedes poner directamente trozos de código usando las etiquetas [code=php] y [/code] o incrustar desde Snipplr.com [snippet=id_snippet]

Compartir: WebeameMeneame Delicious Digg

Preguntas relacionadas