11484 sujets

JavaScript, DOM et API Web HTML5

Bonjour,

Cela fait plusieurs semaines que j'épluche les forums et notament le très bon Alsacreations pour trouver une piste mais en vain.

Voilà mon problème :
J'ai un fichier XML stocké sur un serveur de fichiers accessible uniquement sur un réseau local.
J'ai un serveur distant accessible par Internet.

Je dois transmettre ce fichier (ou son contenu) du serveur de fichiers vers le serveur distant. Smiley deal

Je pense passer par un client du réseau local qui a accès à Internet :
1) Le serveur distant demande au client de rapatrier le fichier.
2) Le client fait la demande de fichier au serveur de fichiers (avec XmlHttprequest par exemple).
3) Le serveur de fichiers répond et envoi le fichier au client (plutôt un objet DOM en fait).
4) Le client renvoi ce fichier au serveur distant.

J'ai réussi à faire les étapes 1) à 3) à peu près (je n'arrive pas a stocker l'objet DOM renvoyé par le serveur de fichiers). Smiley sweatdrop

Je fais donc appel à votre aide pour me donner des pistes car je suis au bout du rouleau... Smiley bawling
Modifié par quentin_ler (14 Aug 2007 - 10:33)
Administrateur
Bonjour,

le fichier en local est visible de l'extérieur? De quelle manière (étape 1), j'ai pas bien suivi ...
Modifié par Felipe (14 Aug 2007 - 12:30)
Bonjour,
Le fichier, pour des raisons de sécurité, n'est pas visible d'Internet, uniquement du réseau local au serveur de fichier.
Le client, étant sur le même réseau que le serveur de fichier, voit le fichier.
Le serveur distant, n'étant pas sur le même réseau, ne voit pas le fichier.
Salut,
le problème dans tout ça c'est l'accès au différent domaines (serveur de download et serveur d'upload) pour ça il te faut forcément l'utilisation d'une frame :
XMLHTTPRequest d'un coté et un formulaire dans la frame de l'autre ... ou l'utilisation XMLHTTPRequest des 2 coté dont l'un est dans la frame (sans doute la meilleure façon).

La page hôte (venant du serveur local) et la frame (serveur distant) s'occupe séparément des différents transferts. La page hôte charge le fichier et le stocke dans une variable pour quelle soit accessible à la frame dès que celui ci est terminé la frame l'envoi au serveur distant.

Bon le seul bout de code que j'ai déja c'est :
index.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Test File put in POST Method</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <style type="text/css">
      pre
      {
        background: rgb(220, 220, 220);
        border: 1px solid rgb(200, 200, 200);
        padding: 1em;
        font-family: "Lucida Console";
        color: rgb(40, 40, 40);
      }
    </style>
    <script type="text/javascript">
      var XHR = new XMLHttpRequest();
      XHR.open('POST', 'index.php?nocache=' + (new Date()).getTime(), false);
      
      var boundary = 'fileSection';
      var variableName = 'userfile';
      var fileName = 'test.txt';
      var fileMimeType = 'text/plain';
      var fileContent = 'contents of file';
      
      XHR.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' + boundary);
      XHR.onreadystatechange = function()
      {
        if(XHR.readyState == 4)
          if(XHR.status == 200)
            logConsole.innerHTML = XHR.responseText;
      };
      var content = '--' + boundary + '\n' +
                    'Content-Disposition: form-data; name="' + variableName + '"; filename="' + fileName + '"\n' +
                    'Content-Type: ' + fileMimeType + '\n' +
                    '\n' +
                    fileContent + '\n' +
                    '--' + boundary + '--';
      
      var logConsole;
      window.onload = function()
      {
        logConsole = document.getElementById('logConsole');
        XHR.send(content);  
      }
    </script>
  </head>
  <body>
    <pre><code id="logConsole"></code></pre>
  </body>
</html>


index.php
<?php
echo '$_FILES = ';
var_dump($_FILES);
echo "\n". 'file_get_contents(\'php://input\') = ';
var_dump(file_get_contents('php://input'));
?>


Ces code vont te permettre de tester l'envois virtuel (ou généré à la volé) de fichier :
Un fichier nommé "test.txt" contenant le text ("text/plain") suivant "contents of file" va être envoyé au serveur qui sera récupérable sous le nom de variable $_POST["userfile"].

J'ai réalisé ce petit script pour voir comment on pouvais faire pour envoyer un fichier avec XMLHttpRequest. Je me suis aidé des entêtes HTTP fournies par LiveHTTPHeaders
donc voici un exemple d'envois de fichier avec un formulaire basique :
POST /test_post_method/index.php HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer:  http://127.0.0.1/test_post_method/upload.html
 
Content-Type: multipart/form-data; boundary=---------------------------226482744623805
Content-Length: 240
-----------------------------226482744623805
Content-Disposition: form-data; name="userfile"; filename="test.txt"
Content-Type: text/plain

contenu du fichier text

2 retour à la ligne
-----------------------------226482744623805--


J'espère que ça va grandement t'aider Smiley smile
Bonjour heyman85,
Un très très grand merci pour cette solution qui semble envisageable.
Toutefois, j'ai essayé toute la matinée de faire marcher ton code mais je crois que je n'ai pas tout compris et je m'en excuse d'avance...

Où dois-je placer index.html et index.php ?
j'ai essayé avec index.php sur le serveur de fichiers (là ou se trouve mon fichier source), avec un test.txt (contenant une phrase) et index.html sur le serveur distant.
J'appelle index.html de mon client, firefox refuse d'executer XmlHttpRequest.open et IE aussi (Erreur : "XMLHttpRequest est indéfini").

J'ai essayé en laissant index.html sur le serveur de fichier, j'ai bien
$_FILES = array(1) {
  ["userfile"]=>
  array(5) {
    ["name"]=>
    string(8) "test.txt"
    ["type"]=>
    string(10) "text/plain"
    ["tmp_name"]=>
    string(41) "C:/Program Files/EasyPHP1-8\tmp\php59.tmp"
    ["error"]=>
    int(0)
    ["size"]=>
    int(16)
  }
}

file_get_contents('php://input') = string(0) ""

mais que comprendre ? Et comment voir le contenu du ficher ?

J'ai compris que le contenu du fichier est censé être dans $_POST["userfile"] mais je ne vois pas comment afficher cette variable.
En fait mon script ne fait que envoyer un faux fichier au serveur.

Le but est de faire comme un input[type=file] avec XMLHttpRequest : envoyer un fichier.
Sauf que le fichier en question pour XMLHttpRequest il n'existe pas forcément.

Dans ton cas, il va falloir déja récuper le contenu du vrai fichier à transferer, son nom et mimeType (pas obligatoire).

Pour les codes que j'ai donné en exemple il faut mettre les 2 fichiers dans le même dossier web. Le fichier "test.txt" n'est pas utile dans ma démo.

Je suis désolé de pas avoir donné plus. En réalité il reste pas mal de chose à faire.
Pour le moment, pour que le code sois le plus simple possible, j'ai fait dans les standard, donc pas d'activeX pour IE.
Il te reste donc à faire :
la récupération du fichier à transferer (contenu, nom, type)
une fois le fichier chargé, envoyer le contenu récupéré à l'aide du code que j'ai donné.
Enfin mettre en place pour que la récupération et l'envoi ce fasse sur des domaines différents (locale et distant).

Pour le coté serveur, voila un peut d'aide :
http://fr.php.net/manual/fr/features.file-upload.php
http://fr.php.net/manual/fr/function.file.php
Modifié par heyman85 (17 Aug 2007 - 12:07)
Merci, je suis toujours un peu largué, je ne comprends pas pourquoi le contenu du fichier ne s'affiche pas
file_get_contents('php://input') = string(0) ""


De plus aurais-tu une idée pour que l'ordinateur qui appelle la page index.html récupère les infos qu'elle affiche ?
file_get_contents('php://input') = string(0) ""

Cette partie de code n'est la que pour indication. Pour PHP elle permet de récuperer les données non nommé passé en POST. Dans l'exmple, PHP reconnais que un fichier à été envoyé en POST et le gère directement. C'est pour cela que l'on peut y acceder par l'intermédiaire de $_FILES.

Lorsque PHP reçois un fichier il le stock dans un répertoire temporaire ("C:/Program Files/EasyPHP1-8\tmp" pour ton install d'EasyPHP). Tu peut acceder au fichier par le chemin indiqué par la variable $_FILES["userfile"]["tmp_name"] (pour notre exemple ici).
Si tu veux déplacer ce fichier il faut suivre l'exemple donné dans la page citée précédemment (http://fr.php.net/manual/fr/features.file-upload.php)

Coté serveur (PHP), la démarche est semblable au fonctionnement habituel :
<form action="index.php">
  <input type="file" name="userfile" />
  <input type="submit" value="Envoyer" />
</form>
Bonjour,

Je dois faire quasiment la même chose pour envoyer un fichier XML mais d'un serveur distant à un autre serveur distant.
On m'a donné une adresse à qui envoyer le fichier et cela marche trés bien de local à distant ou bien même de distant à distant MAIS à condition de baisser le niveau de sécurité de IE au niveau 2.
L'explication est là: http://msdn2.microsoft.com/fr-fr/library/ms537505(en-us).aspx#xdomain
et en résumé: Il est impossible de faire du cross-domain (ie d'accéder à une page d'un domaine extérieur à un autre) avec l'objet XMLHTTP pour des raisons de sécurité...sauf en baissant le niveau de sécurité de IE

Connaissez vous une autre méthode pour envoyer un fichier à une page sur un serveur distant sans avoir ce problème de sécurité?

D'ailleurs, ensuite il devra y avoir un CRON qui envoie les XML automatiquement pour une mise à jour quotidienne...Du coup le javascript serait à proscrire. Donc définitivement, il faut que je trouve une solution d'envoi de fichier XML par PHP à une adresse spécifique qui ne prend pas de variable mais recoit bien le fichier XML en javascript avec le code ci-dessous. Est ce possible pour vous?

Le serveur d'envoi est en PHP, celui de réception du fichier est en ASP.

Voilà le code qui peut peut être servir à d'autres personnes n'ayant pas les mêmes contraintes... :

<html><XML ID="Transaction"><Transaction>
<LoginDetails>
	<Email>email_login_de_connection</Email>
	<Password>pwd_servant_a_connection</Password>
</LoginDetails>
<JobDetails>
<JobRefNo>jobref123</JobRefNo>
<JobTitle>Titre du job</JobTitle>
<JobExpiry>60</JobExpiry>
<JobContactName>Toto la Riflette</JobContactName>
<JobContactEmail>toto@lariflette.com</JobContactEmail>
<JobRoom>1</JobRoom>
<JobShortDesc>Petite description du job</JobShortDesc>
<JobDetDesc><![CDATA[ <B>Grande desription</B> du job avec TAG HTML </BR>.... ]]></JobDetDesc>
<JobCategories>8</JobCategories>
<JobLocations>96</JobLocations>
<JobSalaryRange>0</JobSalaryRange>
<JobType>1</JobType>
<JobRoles>3285</JobRoles>
<JobMinExp>1</JobMinExp>
<JobMinQual>0</JobMinQual>
<JobQues1></JobQues1>
<JobQues2></JobQues2>
<JobQues3></JobQues3>
</JobDetails>
</Transaction>
</XML>
<script language="javascript">var httpOb = new ActiveXObject("Msxml2.XMLHTTP");
httpOb.open("POST","http://www.irishjobs.ie/VacManager/AddV2_XML.asp", false);
var TransactionObj = Transaction.XMLDocument.documentElement;httpOb.send(Transaction.XMLDocument);
if(httpOb.status==200){location.href="../irishjobs_file_trt2.php?id_job=939"}else{location.href="../irishjobs.php?alert=2"}</script></html>


Un grand merci déjà à ceux qui ont lu jusqu'au bout et en espérant que cela en inspire au moins un!
Modifié par gueridon (25 Jan 2008 - 10:20)