2010-02-26 3 views
0

J'ai besoin de tester divers services Web qui sont des messages qui prennent un fichier téléchargé en tant que contenu du corps. Pour ce faire, je voudrais faire des tests rapides en utilisant l'appel ajax. J'ai trouvé la page suivante qui décrit comment faire ceci: http://www.captain.at/ajax-file-upload.php Cependant, il faut que la page ait les privilèges "UniversalXPConnect" dans firefox.Comment activer UniversalXPConnect pour une page Web donnée?

Comment activer ce privilège? J'essayé de modifier prefs.js et en ajoutant:

user_pref("capability.principal.foo.id", "http://localhost:8080/access/index.html"); 
user_pref("capability.principal.foo.granted", "UniversalXPConnect"); 

qui devrait donner accès à la page http://localhost:8080/access/index.html. Mais ça ne semble pas fonctionner.

Répondre

1

Amélioration de la réponse de Panzi, vous pouvez utiliser l'objet FormData pour envoyer des fichiers avec l'Ajax d'une manière très simple:

<html> 
<head> 
<title>HTML5 File API</title> 
</head> 
<script type="text/javascript"> 
// <!-- 
// See: https://developer.mozilla.org/En/XMLHttpRequest/Using_XMLHttpRequest#Using_FormData_objects 
function upload() { 
    var uploadRequest = new XMLHttpRequest, 
     uploadForm = document.getElementById('file_upload'); 

    function transferProgress(progressEvent) { 
    /*Executes For each update of the progress of the Ajax transfer.*/ 
     // show progress bar or something.... 
    } 
    function transferComplete() { 
    /*Executes when the transfer is complete.*/ 
     //Do something like show a nice message... 
    } 
    function transferFailed() { 
    /*Executes when the transfer fails.*/ 
     alert('Upload failed!'); 
    } 
    function transferCanceled() { 
    /*Executes when the transfer is canceled.*/ 
     alert('Upload canceled!'); 
    } 

    uploadRequest.upload.addEventListener('progress', transferProgress, false); 
    //uploadRequest.upload.addEventListener('load', transferComplete, false); // transfer complete, but this doesn't mean a response from the server has been received. 
    uploadRequest.addEventListener('load', transferComplete, false); // ajax request complete, response from the server has been received and all has been processed. 
    uploadRequest.upload.addEventListener('error', transferFailed, false); 
    uploadRequest.upload.addEventListener('abort', transferCanceled, false); 

    uploadRequest.open('POST', action, true); 
    uploadRequest.send(new FormData(uploadForm)); 
} 
// --> 
</script> 
<body> 
<form id="file_upload" enctype="multipart/form-data"> 
    <input type="text" id="text" value="blah blah blah"/> 
    <input type="file" onchange="upload();"/> 
</form> 
</body> 
</html> 
+1

En effet, c'est plus simple. Je ne connaissais tout simplement pas FormData quand j'ai écrit ma réponse. Upvoted le vôtre. – panzi

+0

Lol. J'ai d'abord utilisé votre méthode puis découvert FormData. – trusktr

1

Si l'utilisateur spécifie le fichier, vous n'avez pas besoin d'UniversalXPConnect. L'API File HTML5 est assez:

<html> 
<head> 
<title>HTML5 File API</title> 
</head> 
<script type="text/javascript"> 
// <!-- 
// See: http://dev.w3.org/2006/webapi/FileAPI/ 

function upload (input) { 
    for (var i = 0; i < input.files.length; ++ i) { 
     // makes multiple uploads 
     uploadFile(input.files[i]); 
    } 
} 

function uploadFile (file) { 
    var reader = new FileReader(); 
    reader.onprogress = function (event) { 
     var percent = 100 * event.loaded/event.total; 
     // TODO: display progress 
    }; 

    reader.onerror = function (event) { 
     // display error 
     alert(errorMessage(reader.error)+': '+file.name); 
    }; 

    reader.onload = function (event) { 
     if (reader.error) { 
      // display error 
      alert(errorMessage(reader.error)+': '+file.name); 
     } 
     else { 
      // You could also use reader.readAsBinaryString(file) 
      // and the mozilla specific function call btoa(reader.result). 
      // For more mozilla specific stuff (e.g. sending data as binary) 
      // see: https://developer.mozilla.org/en/using_xmlhttprequest 
      var data = reader.result.substring(reader.result.search(',')+1); 
      var text = document.getElementById('text').value; 
      var request = new XMLHttpRequest(); 
      var boundaryString = guid(); 
      var boundary = '--' + boundaryString; 

      while (text.search(boundary) != -1) { 
       boundaryString = guid(); 
       boundary = '--' + boundaryString; 
      } 

      var requestbody = boundary + '\n' + 
       'Content-Disposition: form-data; name="mytext"\n' + 
       '\n' + 
       text + 
       '\n' + 
       boundary + '\n' + 
       'Content-Disposition: form-data; name="myfile"; filename="' + 
       file.name.replace(/"/g, '') + '"\n' + 
       'Content-Type: application/octet-stream\n' + 
       'Content-Transfer-Encoding: base64\n' + 
       '\n' + 
       data + '\n' + 
       boundary; 

      request.onreadystatechange = function() { 
       if (request.readyState == 4) { 
        if (request.status == 200) { 
         alert('Result: ' + request.responseText); 
        } 
        else { 
         alert(
          'Error "' + request.statusText + '" occured while uploading: ' + 
          file.name); 
        } 
       } 
      }; 

      /* a non-standard variant (still supported by many browsers) would be: 
      request.onuploadprogress = function() { 
       // possibly only mozilla, but awesome! upload progress! 
       var percent = 100 * event.loaded/event.total; 
       // TODO: display progress 
      }; 

      request.onload = function() { 
       if (request.status == 200) { 
        alert('Result: ' + request.responseText); 
       } 
       else { 
        alert(
         'Error "' + request.statusText + '" occured while uploading: ' + 
         file.name); 
       } 
      }; 

      request.onerror = function() { 
       alert(
        'There was a problem with the request when uploading file: ' + 
        file.name); 
      }; 
      */ 

      request.open('POST', 'post.php', true); 
      request.setRequestHeader('Content-type', 'multipart/form-data; boundary="' + 
       boundaryString + '"'); 
      request.setRequestHeader('Connection', 'close'); 
      request.setRequestHeader('Content-Length', requestbody.length); 
      request.send(requestbody); 

     } 
    }; 

    reader.readAsDataURL(file); 

    // there would also be: 
    // reader.readAsBinaryString(file); 
    // reader.readAsText(file, 'UTF-8'); 
    // reader.readAsArrayBuffer(file); 
} 

function errorMessage (error) { 
    switch (error.code) { 
     case FileError.ABORT_ERR: 
      return 'Aborted'; 

     case FileError.ENCODING_ERR: 
      return 'Encoding Error'; 

     case FileError.NOT_FOUND_ERR: 
      return 'File not found'; 

     case FileError.NOT_READABLE_ERR: 
      return 'File is not readable'; 

     case FileError.NO_MODIFICATION_ALLOWED_ERR: 
      return 'File is not writeable'; 

     case FileError.SECURITY_ERR: 
      return 'Security Error'; 

     default: 
      return 'Unknown error code: ' + error.code; 
    } 
} 

// from: https://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript 
function S4() { 
    return (((1+Math.random())*0x10000)|0).toString(16).substring(1); 
} 

function guid() { 
    return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4()); 
} 

// --> 
</script> 
<body> 
<input type="text" id="text" value="My text.."/> 
<input type="file" onchange="upload(this);"/> 
</body> 
</html> 

encore, je recommande d'utiliser un iframe, car il est mieux pris en charge par tous les navigateurs: Is it possible to use Ajax to do file upload?

+0

Si vous travaillez pour une entreprise face à des centaines de milliers de dollars de clients, ne seraient pas en situation d'insécurité iframes (ce que j'ai entendu)? L'API de fichiers est la voie à suivre, ou de bonnes mises à jour de page. – trusktr

+0

@trusktr: Dans la guerre, les iframes sont-ils plus dangereux que UniversalXPConnect? Et les risques de sécurité des iframes ne sont pas liés à leur utilisation, mais à la possibilité d'utiliser votre page en une seule fois. Ou désactivez-vous les iframes pour l'ensemble de votre site Web et ne pouvez même pas l'activer pour une page de soumission? Vous pouvez utiliser un jeton d'authenticité pour éviter les abus. Même un contrôle de référence pourrait suffire. – panzi

+0

Nous désactivons toutes les iframes sur l'ensemble du site et envoyons des choses par courrier avec AJAX en utilisant l'objet FormData super génial. Vérifiez-le sur le réseau de développeurs Mozilla: https://developer.mozilla.org/en/DOM/XMLHttpRequest/Using_XMLHttpRequest#Using_FormData_objects Le comportement que vous obtenez est le navigateur se comporter EXACTEMENT comme de bonnes actualisations de page à la mode, sauf maintenant vous pouvez faire tout cela dans Ajax sans actualiser la page pour envoyer un formulaire (y compris les téléchargements de fichiers). – trusktr

Questions connexes