Ecriture de fichier sur poste client 'avec' ajax + PHP

Eléphanteau du PHP | 19 Messages

24 sept. 2014, 12:36

Bonjour,

J'utilise un code PHP très simple pour demander (grace aux 'headers') à l'utilisateur un nom de fichier local dans lequel seront enregistrées des informations.
Ca fonctionne, voici le code: (test_export_direct.php)
<?php
header('Content-type: text/plain');
header('Content-Disposition: attachment; filename="export_direct.txt"');

echo "Ligne 1 \n";
echo "Ligne 2 \n";

?>
Ca demande le nom du fichier (avec la valeur par defaut que j'ai fournie) et ça enregistre les 2 lignes dedans, sur le poste local.

Maintenant, je veux faire la même chose en Ajax:
J'ai un écran principal, avec un bouton export et du code javascript pour appeler une page php qui 'devrait ecrire' dans le fichier choisi, mais qui ne fait rien du tout:

La page principale (code js + bouton): (test_export_ajax.php)
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta http-equiv="Content-Type" content="text/html" charset="utf-8">
<script type="text/javascript">

// Instancie un objet XMLHttpRequest et le renvoie
function getXMLHttpRequest() {
	"use strict";
	var xhr = null;
	
	if (window.XMLHttpRequest || window.ActiveXObject) {
		if (window.ActiveXObject) {
			try {
				xhr = new ActiveXObject("Msxml2.XMLHTTP");
			} catch(e) {
				xhr = new ActiveXObject("Microsoft.XMLHTTP");
			}
		} else {
			xhr = new XMLHttpRequest(); 
		}
	} else {
		alert("Votre navigateur ne supporte pas l'objet XMLHTTPRequest...");
		return null;
	}
	
	return xhr;
}

function exportation() {
	"use strict";
	
	var xhr = getXMLHttpRequest();

	var scriptphp = "test_export_ajax_appel.php";

	// j'appelle le formulaire en synchrone
	xhr.open('POST', scriptphp, false);
	// a partir de la, je navigue un peu dans le brouillard... car rien ne semble se passer
	xhr.setRequestHeader('Content-type', 'text/plain');
	xhr.setRequestHeader('Content-Disposition', 'attachment; filename="export_ajax.txt"');
	xhr.send(null); // je n'ai pas de parametre a passer
	// juste pour voir que ça s'est terminé...
	alert('Fini!');
}

</script>

<title>Export avec AJAX</title>
</head>
<body>

<button
	onclick="javascript: exportation();"
>Export
</button>
</body>
</html>
La page PHP appelée (test_export_ajax_appel.php) :
<?php

echo "Ligne 1 \n";
echo "Ligne 2 \n";

?>
Rien ne se passe, je ne comprends pas...

Merci pour votre aide :)
Modifié en dernier par wolflarsen le 24 sept. 2014, 16:38, modifié 3 fois.

Eléphant du PHP | 151 Messages

24 sept. 2014, 12:59

Ben écoute... Ton code fonctionne chez moi, mais il ne fait pas d'attachment au fichier txt qui n'est créé nulle part.
Le echo se passe bien pour les ligne 1 et 2, même droit à ton alert.
Fais un F12 sur ton navigateur (chrome en tout cas), regarde les flux et constate.
Tu n'as plus qu'à passer tes variables, et enregsitrer ce que tu veux via un ob_ et cie.
Développeur d'applications pour intranets industriels (IHM), DBA Oracle, auto entrepreneur. Je fuis les frameworks car je pense comme Rasmus Lerdorf : "all PHP frameworks suck"...
Je me suis lancé dans la reprise du projet PhpMyNewsletter (GNU GPL), que je vous invite à essayer.

echo ($user=='enregistré?"je t'aide":"je t'aide pas !");

Eléphanteau du PHP | 19 Messages

24 sept. 2014, 14:05

Merci.
Oui le code 'fonctionne' (j'évite de poster des bugs :? ) mais ne fait pas la même chose que la version 'directe'.

Par contre je n'ai pas très bien compris ce que tu suggères avec " ob_ " etc.

Eléphant du PHP | 151 Messages

24 sept. 2014, 16:20

Et que donne la version directe alors ?
Développeur d'applications pour intranets industriels (IHM), DBA Oracle, auto entrepreneur. Je fuis les frameworks car je pense comme Rasmus Lerdorf : "all PHP frameworks suck"...
Je me suis lancé dans la reprise du projet PhpMyNewsletter (GNU GPL), que je vous invite à essayer.

echo ($user=='enregistré?"je t'aide":"je t'aide pas !");

Eléphanteau du PHP | 19 Messages

24 sept. 2014, 16:34

ce que j'ai écrit:
Ca demande le nom du fichier (avec la valeur par defaut que j'ai fournie) et ça enregistre les 2 lignes dedans, sur le poste local.

Eléphant du PHP | 151 Messages

24 sept. 2014, 21:41

Mets tout ton code, celui demande les lignes aussi, et quand tu dis en local, ça veut dire sur la station de celui qui écrit ?
Développeur d'applications pour intranets industriels (IHM), DBA Oracle, auto entrepreneur. Je fuis les frameworks car je pense comme Rasmus Lerdorf : "all PHP frameworks suck"...
Je me suis lancé dans la reprise du projet PhpMyNewsletter (GNU GPL), que je vous invite à essayer.

echo ($user=='enregistré?"je t'aide":"je t'aide pas !");

Eléphanteau du PHP | 19 Messages

25 sept. 2014, 10:10

Bonjour,

J'ai déjà tout mis (je pense)

La version de référence
"test_export_direct.php"
Qui fonctionne: elle demande un nom de fichier (qui sera local=sur le poste client) et y écrit tout ce que le script 'envoie' (=echo 'xxx')


La version ajax, 2 fichiers:
"test_export_ajax.php"
Qui contient (partie html) un bouton qui appelle une fonction JS et (partie JS) le code qui appelle en Ajax la page PHP d'action
"test_export_ajax_appel.php"
Qui contient ce qui sera écrit dans le fichier.

Pour la partie JS qui définit les headers, je fais ça un peu au pif, mais le cheminement me paraissait logique...

Eléphant du PHP | 151 Messages

25 sept. 2014, 10:24

Alors la réalisation n'est pas possible, tu ne peux pas écrire sur la station client.
C'et bien ce que j'avais compris... Tu imagines la faille de sécurité ? Car si tu peux écrire, tu peux détruire... Tu me suis ?
Développeur d'applications pour intranets industriels (IHM), DBA Oracle, auto entrepreneur. Je fuis les frameworks car je pense comme Rasmus Lerdorf : "all PHP frameworks suck"...
Je me suis lancé dans la reprise du projet PhpMyNewsletter (GNU GPL), que je vous invite à essayer.

echo ($user=='enregistré?"je t'aide":"je t'aide pas !");

Eléphanteau du PHP | 19 Messages

26 sept. 2014, 10:22

Hello Arnaud,

Ben si, je peux écrire, la preuve avec le premier programme, rien de plus simple

Essaye ce que j'ai mis en premier:
test_export_direct.php
<?php
header('Content-type: text/plain');
header('Content-Disposition: attachment; filename="export_direct.txt"');

echo "Ligne 1 \n";
echo "Ligne 2 \n";

?>
Je te garantis que ça va écrire

ligne 1
ligne 2

dans un fichier du poste client mais bien sûr l'utilisateur voit qu'on souhaite écrire un fichier, peut en changer le nom par défaut et même en refuser l'écriture.

Il ne faut pas être parano :) ça n'est pas une faille de sécurité et ça fonctionne très bien.
Je cherche juste à comprendre pourquoi ça ne fonctionne pas quand je fais la même chose en Ajax (enfin ce que je pensais être la même chose).

Eléphant du PHP | 151 Messages

26 sept. 2014, 10:30

Alors il travaille sur un serveur web
Parce que je te le dis : php n'ira pas écrire dans un ordinateur client.
Je ne suis pas parano, la preuve : mon linux n'a pas d'antivirus 8-) 8-)
Développeur d'applications pour intranets industriels (IHM), DBA Oracle, auto entrepreneur. Je fuis les frameworks car je pense comme Rasmus Lerdorf : "all PHP frameworks suck"...
Je me suis lancé dans la reprise du projet PhpMyNewsletter (GNU GPL), que je vous invite à essayer.

echo ($user=='enregistré?"je t'aide":"je t'aide pas !");

Eléphanteau du PHP | 19 Messages

26 sept. 2014, 10:40

Je ne sais plus quoi répondre pour te prouver que tu as tort... :shock:

Prend le minuscule bout de code du message au dessus, écris-le dans un fichier test.php sur ton serveur, execute le avec n'importe quel navigateur.
Je te préviens: ça va écrire un fichier sur ton poste ! :)
Mais ce n'est que du texte, pas un virus.

J'apprécie que tu t'intéresse à mon problème, mais ne reste pas bloqué sur des principes (vrais dans une certaine mesure) genre : un script PHP n'écrit rien sur le poste du client.

En l'occurrence, c'est le navigateur qui écrit, pas le script.
C'est exactement ce que je veux, mais en version Ajax !

Eléphanteau du PHP | 19 Messages

26 sept. 2014, 10:52

Un script plus 'réaliste' pour tester
<?php
if ( isset($_GET['valide']) ) {
	header('Content-type: text/plain');
	header('Content-Disposition: attachment; filename="export_direct.txt"');

	echo "Ligne 1 \n";
	echo "Ligne 2 \n";
}
?>
<html>
<head>
</head>
<body>
<form method="get" name="f01" action="<?php $PHP_SELF ?>"> 
<input type="submit" value="Export local" name="valide">
</form>
</body>
</html>

Eléphant du PHP | 151 Messages

26 sept. 2014, 13:03

La ligne suivante :
header('Content-Disposition: attachment; filename="export_direct.txt"');
a pour but théorique d'envoyer un fichier proposé au téléchargement via le navigateur.

Les seules choses qui peuvent écrire du code sur un ordinateur sont les activeX de microsoft dans le navigateur internet explorer. Donc, en tant que vieux développeur expérimenté (administrateur système unix, dba oracle, dollar universe, cft, ayant travaillé sur GCOS7, mainframes, etc...) je peux te dire que php n'ira écrire aucun fichier sur mon ordinateur distant du serveur web.

NB : les seules choses écrites sur une station distante sont les cookies (les sessions étant sur les serveurs).

What else ?
Développeur d'applications pour intranets industriels (IHM), DBA Oracle, auto entrepreneur. Je fuis les frameworks car je pense comme Rasmus Lerdorf : "all PHP frameworks suck"...
Je me suis lancé dans la reprise du projet PhpMyNewsletter (GNU GPL), que je vous invite à essayer.

echo ($user=='enregistré?"je t'aide":"je t'aide pas !");

Eléphanteau du PHP | 19 Messages

26 sept. 2014, 14:11

La ligne suivante :
header('Content-Disposition: attachment; filename="export_direct.txt"');
a pour but théorique d'envoyer un fichier proposé au téléchargement via le navigateur.
Pourquoi 'théorique' ? C'est exactement ce que ça fait.
Les seules choses qui peuvent écrire du code sur un ordinateur sont les activeX de microsoft dans le navigateur internet explorer. Donc, en tant que vieux développeur expérimenté (administrateur système unix, dba oracle, dollar universe, cft, ayant travaillé sur GCOS7, mainframes, etc...) je peux te dire que php n'ira écrire aucun fichier sur mon ordinateur distant du serveur web.
alors, comment appelles-tu le fait d' envoyer un fichier proposé au téléchargement via le navigateur

As-tu exécuté mon script ? Le résultat n'est-il pas un fichier sur ton ordinateur ? (indirectement, mais le résultat est là).

Cela dit, as-tu une idée de la raison pour laquelle, en mode Ajax, ça ne fonctionne pas (ce qui est le but de mon post...) ?

Eléphant du PHP | 151 Messages

26 sept. 2014, 18:04

La ligne suivante :
header('Content-Disposition: attachment; filename="export_direct.txt"');
a pour but théorique d'envoyer un fichier proposé au téléchargement via le navigateur.
Pourquoi 'théorique' ? C'est exactement ce que ça fait.
Les seules choses qui peuvent écrire du code sur un ordinateur sont les activeX de microsoft dans le navigateur internet explorer. Donc, en tant que vieux développeur expérimenté (administrateur système unix, dba oracle, dollar universe, cft, ayant travaillé sur GCOS7, mainframes, etc...) je peux te dire que php n'ira écrire aucun fichier sur mon ordinateur distant du serveur web.
alors, comment appelles-tu le fait d' envoyer un fichier proposé au téléchargement via le navigateur

As-tu exécuté mon script ? Le résultat n'est-il pas un fichier sur ton ordinateur ? (indirectement, mais le résultat est là).

Cela dit, as-tu une idée de la raison pour laquelle, en mode Ajax, ça ne fonctionne pas (ce qui est le but de mon post...) ?
Un téléchargement n'est pas une écriture dans un poste client.
Vu que tu cries, je ne poste plus dans ce fil.
Bye
Développeur d'applications pour intranets industriels (IHM), DBA Oracle, auto entrepreneur. Je fuis les frameworks car je pense comme Rasmus Lerdorf : "all PHP frameworks suck"...
Je me suis lancé dans la reprise du projet PhpMyNewsletter (GNU GPL), que je vous invite à essayer.

echo ($user=='enregistré?"je t'aide":"je t'aide pas !");