Précédent   Forum des professionnels en informatique > Webmasters - Développement Web > JavaScript > Bibliothèques & Frameworks > jQuery
jQuery Forum d'entraide sur le framework jQuery. Avant de poster : Tutoriels jQuery, FAQ jQuery, Tous les tutoriels JavaScript, Toutes les FAQ JavaScript
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 11/06/2011, 15h09   #1
Nouveau Membre du Club
 
Étudiant
Inscription : janvier 2008
Messages : 128
Détails du profil
Informations personnelles :
Localisation : France, Haute Savoie (Rhône Alpes)

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : janvier 2008
Messages : 128
Points : 34
Points : 34
Par défaut Ajax cross-domain qui ne fonctionne pas

Bonjour à tous,

Je fais face à un problème qui vraisemblablement relève de la manière dont jQuery 1.6.1 fait les requêtes cross-domain.
Mon site propose plusieurs sous-domaines dont un qui contient toutes les ressources communes (images, css, js) aux autres. J'ai donc besoin de charger régulièrement des fichiers de configuration par exemple stocké sur ce dernier (qu'on appellera racine.exemple.com dans notre cas).

Lorsque je demande le chargement d'un de ces fichiers de configuration qui se présente sous la forme d'un fichier ini, j'obtiens différents messages suivant le navigateur employé. Voici tout d'abord mon code :
Code javascript :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
 
$.ajax({
	async:false,
	crossDomain:true,
	url:url,
	method:"GET",
	succss:function (data){
		file_details.content = data;
	},
	error:function (xhr, status, error){
		alert("Erreur de chargement du fichier '"+url+"' : "+xhr.responseText+" ("+status+" - "+error+")");
	},
	dataType:'text'
});
Ici, url contient donc l'adresse vers un fichier du type racine.exemple.com/config.ini et on se contente de placer le contenu texte du fichier dans file_details.content en cas de succès.
En cas d'erreur, on affiche les détails du probleme :

- Sous IE9 j'obtiens ce message :
Citation:
Erreur de chargement du fichier 'http://racine.exemple.com/config.ini' : undefined (erreur - Erreur : Accès refusé).
- Alors que sous FF4 :
Citation:
Erreur de chargement du fichier 'http://racine.exemple.com/config.ini' : undefined (error - [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE)" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: http://code.jquery.com/jquery-1.6.1.min.js :: <TOP_LEVEL> :: line 27" data: no])
Je ne comprends pas bien. J'ai également d'y insérer le code qui exploite la méthode YQL mais ca produit le même effet sans différences dans les messages ni les codes d'erreur.

Je précise que la requête se fait en synchrone car j'attends d'avoir chargé toute ma config côté client pour poursuivre. Je souhaite garder le format ini.

Est-ce que quelqu'un aurait une explication?
Merci par avance, bon week end.
fanfouer est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/06/2011, 16h38   #2
Responsable Développement Web

 
Avatar de Bovino
 
Homme Didier Mouronval
Développeur Web
Inscription : juin 2008
Messages : 13 807
Détails du profil
Informations personnelles :
Nom : Homme Didier Mouronval
Âge : 41
Localisation : France, Gironde (Aquitaine)

Informations professionnelles :
Activité : Développeur Web
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : juin 2008
Messages : 13 807
Points : 35 803
Points : 35 803
Citation:
qui vraisemblablement relève de la manière dont jQuery 1.6.1 fait les requêtes cross-domain.
Ben ça relève surtout du fait que jQuery, qui n'est que du JavaScript, n'accepte pas les requêtes cross-domain
__________________
Pas de question technique par MP !
Tout le monde peut participer à developpez.com, vous avez une idée, contactez-moi !
Vous possédez un blog et aimeriez diffuser vos billets sur le forum, contactez-moi !
Mes formations video2brain : La formation complète sur JavaScriptJavaScript et le DOM par la pratiquePHP 5 et MySQL : les fondamentaux
Mon livre sur jQuery
Bovino est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/06/2011, 17h00   #3
Nouveau Membre du Club
 
Étudiant
Inscription : janvier 2008
Messages : 128
Détails du profil
Informations personnelles :
Localisation : France, Haute Savoie (Rhône Alpes)

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : janvier 2008
Messages : 128
Points : 34
Points : 34
Citation:
Envoyé par Bovino Voir le message
jQuery, qui n'est que du JavaScript, n'accepte pas les requêtes cross-domain
Bonjour Bovino, merci de ta réponse.

Je me permets de te poser la question de but en blanc : Alors à quoi sert le paramètre "crossDomain" dans les options de la fonction ajax() ?
Cela fait deux ans que j'utilise le hack avec YQL et jQuery arrive sans problèmes à me charger du HTML depuis mon sous-domaine racine.exemple.com vers d'autres sous-domaines.

Voici un exemple qui fonctionne avec l'interface de la carte : on observe clairement la période de build après le chargement du DOM, tout le HTML de l'interface est chargé depuis un autre domaine que le www
http://www.infos-reseaux.com/apps/AD...=webVRD_client

Alors pourquoi cela serait-il différent pour mon fichier .ini?
fanfouer est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/06/2011, 21h19   #4
Rédacteur
 
Avatar de danielhagnoul
 
Homme Daniel Hagnoul
Étudiant perpétuel
Inscription : février 2009
Messages : 3 221
Détails du profil
Informations personnelles :
Nom : Homme Daniel Hagnoul
Âge : 61
Localisation : Belgique

Informations professionnelles :
Activité : Étudiant perpétuel
Secteur : Enseignement

Informations forums :
Inscription : février 2009
Messages : 3 221
Points : 6 767
Points : 6 767
Bonsoir

Citation de la FAQ jQuery :
Citation:
En raison de restrictions de sécurité imposées par Cross-Origin Resource Sharing, les transactions AJAX sont soumises à la politique de même origine, la requête AJAX ne parvient pas à récupérer les données d'un autre domaine, d'un sous domaine, ou d'un autre protocole. Seules les transactions AJAX manipulant des scripts et du JSONP ne sont pas soumises à ces restrictions.
Extrait de la documentation AJAX :

Citation:
crossDomain(added 1.5) Default: false for same-domain requests, true for cross-domain requests

If you wish to force a crossDomain request (such as JSONP) on the same domain, set the value of crossDomain to true. This allows, for example, server-side redirection to another domain
Citation:
asyncBoolean Default: true

By default, all requests are sent asynchronously (i.e. this is set to true by default). If you need synchronous requests, set this option to false. Cross-domain requests and dataType: "jsonp" requests do not support synchronous operation. Note that synchronous requests may temporarily lock the browser, disabling any actions while the request is active.
__________________

FAQ jQuery

Mon cahier d’exercices sur jQuery & Co

Si un message vous a aidé ou vous semble pertinent, votez pour lui !
danielhagnoul est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/06/2011, 01h08   #5
Nouveau Membre du Club
 
Étudiant
Inscription : janvier 2008
Messages : 128
Détails du profil
Informations personnelles :
Localisation : France, Haute Savoie (Rhône Alpes)

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : janvier 2008
Messages : 128
Points : 34
Points : 34
Bonsoir Danihagnoul, merci de ta réponse.

En fait pour moi les deux premières citations sont contradictoires, AJAX peut s'appuyer sur des requêtes cross-domain depuis l'intronisation de l'XDomainRequest, ce que doit exploiter jQuery.
C'est pour cette raison que j'ai bâti mon raisonnement sur le fait que je pouvais faire du cross-domain. Et le hack qui consiste à appeler YQL qui lui-même va chercher la ressource désirée marchait avant l'apparition d'XDomainRequest.

Bref, il est bien dommage que ce ne soit possible qu'en asynchrone comme le laisse entendre la 3ième citation mais je m'en contenterai. J'ai toujours un message d'erreur même si ce n'est plus le même sous FF4:

-Sous FF4 :
Citation:
Erreur de chargement du fichier 'http://racine.exemple.com/config.ini' : (error - )
-Sous IE9 :
Citation:
Erreur de chargement du fichier 'http://racine.exemple.com/config.ini' : undefined (erreur - Erreur : Accès refusé).
Inutile d'affirmer que j'ai la certitude que mon fichier existe bien sur le serveur
Mais alors pourquoi cela ne fonctionne-t-il pas?
fanfouer est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/06/2011, 02h08   #6
Rédacteur
 
Avatar de danielhagnoul
 
Homme Daniel Hagnoul
Étudiant perpétuel
Inscription : février 2009
Messages : 3 221
Détails du profil
Informations personnelles :
Nom : Homme Daniel Hagnoul
Âge : 61
Localisation : Belgique

Informations professionnelles :
Activité : Étudiant perpétuel
Secteur : Enseignement

Informations forums :
Inscription : février 2009
Messages : 3 221
Points : 6 767
Points : 6 767
Bonsoir

Je ne suis pas un expert en AJAX et en PHP, mais je crois savoir que :
  • l'XMLHttpRequest cross-domain (la version 2 de l'XMLHttpRequest) n'est pas implémenté par tous les navigateurs ;
  • que le site appelé doit autoriser la transaction par un : header("Access-Control-Allow-Origin: *"); ;
  • que XDomainRequest() est spécifique à IE.
__________________

FAQ jQuery

Mon cahier d’exercices sur jQuery & Co

Si un message vous a aidé ou vous semble pertinent, votez pour lui !
danielhagnoul est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 12/06/2011, 02h57   #7
Nouveau Membre du Club
 
Étudiant
Inscription : janvier 2008
Messages : 128
Détails du profil
Informations personnelles :
Localisation : France, Haute Savoie (Rhône Alpes)

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : janvier 2008
Messages : 128
Points : 34
Points : 34
Très bien, je prends bonne note de tout cela.

Cependant pour la deuxième remarque, c'est ce que j'ai cherché à faire pendant un temps mais vu qu'il s'agit d'un fichier à part entière non généré par PHP, je me demande comment je peux spécifier des en-têtes supplémentaires.
En passant par un fichier htaccess peut-être?

Dans un contexte plus large, il m’intéresserait également de ne rendre disponibles les ressources de mon sous-domaine racine.exempl... qu'à seulement tout autre sous-domaine du domaine principal vu qu'il s'agit de ressources annexes (images/css/js) et non de contenu à proprement parler.

Cette modification solutionnera peut-être mon problème, peux-tu m'en dire plus?
fanfouer est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/06/2011, 09h09   #8
Rédacteur
 
Avatar de danielhagnoul
 
Homme Daniel Hagnoul
Étudiant perpétuel
Inscription : février 2009
Messages : 3 221
Détails du profil
Informations personnelles :
Nom : Homme Daniel Hagnoul
Âge : 61
Localisation : Belgique

Informations professionnelles :
Activité : Étudiant perpétuel
Secteur : Enseignement

Informations forums :
Inscription : février 2009
Messages : 3 221
Points : 6 767
Points : 6 767
Bonjour

On peut bien entendu limiter l'autorisation :
Code :
1
2
3
4
<?php
header("Access-Control-Allow-Origin: *");              // Tous les domaines
header("Access-Control-Allow-Origin: developpez.com");    // Seuls developpez.com et ses sous-domaines peuvent y accéder
?>
Pour plus d'options, voir : Cross-Origin Resource Sharing

Je n'ai jamais utilisé le Cross-domain, vous en savez maintenant plus que moi. Mais sur le forum PHP il y a sûrement quelqu'un de plus compétent sur ce sujet.

[Edit]

Citation de la FAQ jQuery : Comment dois-je formuler une requête AJAX ?

Citation:
Nota bene :

À cause des restrictions imposées par : Cross-Origin Resource Sharing, sans un serveur pour donner les réponses attendues par le navigateur on n'obtient plus que des erreurs et des avertissements.

Ainsi je n'arrive plus à travailler sur mon ordinateur avec un simple fichier JSON et une page HTML affichée dans Firefox 3.6.13 ou Chrome 9.0.597.86. Je suis obligé de sauvegarder la page web (qui ne contient pourtant que du code HTML) comme une page PHP et d'utiliser un serveur PHP (WampServer).
__________________

FAQ jQuery

Mon cahier d’exercices sur jQuery & Co

Si un message vous a aidé ou vous semble pertinent, votez pour lui !
danielhagnoul est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/06/2011, 09h45   #9
Responsable Développement Web

 
Avatar de Bovino
 
Homme Didier Mouronval
Développeur Web
Inscription : juin 2008
Messages : 13 807
Détails du profil
Informations personnelles :
Nom : Homme Didier Mouronval
Âge : 41
Localisation : France, Gironde (Aquitaine)

Informations professionnelles :
Activité : Développeur Web
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : juin 2008
Messages : 13 807
Points : 35 803
Points : 35 803
Citation:
Envoyé par fanfouer
Alors à quoi sert le paramètre "crossDomain" dans les options de la fonction ajax() ?
Le code jQuery répondra mieux que moi
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
if ( s.crossDomain ) {
 
		var script,
			head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement;
 
		return {
 
			send: function( _, callback ) {
 
				script = document.createElement( "script" );
 
				script.async = "async";
 
				if ( s.scriptCharset ) {
					script.charset = s.scriptCharset;
				}
 
				script.src = s.url;
Comme l'a déjà indiqué Daniel, crossDomain, qui ne s'applique qu'aux scripts permet de créer une balise script et de l'intégrer dans la page. Ce qui explique aussi l'impossibilité de mode synchrone puisque seuls les scripts rencontrés avant la fermeture du DOM sont chargés de façon synchrone.
__________________
Pas de question technique par MP !
Tout le monde peut participer à developpez.com, vous avez une idée, contactez-moi !
Vous possédez un blog et aimeriez diffuser vos billets sur le forum, contactez-moi !
Mes formations video2brain : La formation complète sur JavaScriptJavaScript et le DOM par la pratiquePHP 5 et MySQL : les fondamentaux
Mon livre sur jQuery
Bovino est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/06/2011, 16h24   #10
Nouveau Membre du Club
 
Étudiant
Inscription : janvier 2008
Messages : 128
Détails du profil
Informations personnelles :
Localisation : France, Haute Savoie (Rhône Alpes)

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : janvier 2008
Messages : 128
Points : 34
Points : 34
Citation:
Envoyé par danielhagnoul Voir le message
Bonjour

On peut bien entendu limiter l'autorisation :
Code :
1
2
3
4
<?php
header("Access-Control-Allow-Origin: *");              // Tous les domaines
header("Access-Control-Allow-Origin: developpez.com");    // Seuls developpez.com et ses sous-domaines peuvent y accéder
?>
Pour plus d'options, voir : Cross-Origin Resource Sharing
Vu que tout cela est pour PHP et que je ne me demande même pas si on peut modifier les vhosts Apache chez un hébergeur mutualisé bien connu, j'ai créé un script PHP qui m'affiche le contenu de mon fichier ini bit à bit et qui modifie les headers au passage avec le code suivant :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
 
header ("Access-Control-Allow-Origin:*", true);
 
$file = $_GET["file"];
 
if (is_file ("./".$file.".ini")){
	header ("Content-Type:text/plain");
 
	readfile("./".$file.".ini");
}else{
	echo "404";
}
Les appels aux fichiers se feront donc comme ça : http://racine.exemple.com/getFile?file=config

J'ai les en-têtes HTTP suivante dans la réponse
Citation:
HTTP/1.1 200 OK
Date: Sun, 12 Jun 2011 14:18:15 GMT
Server: Apache/2.2.X (OVH)
X-Powered-By: PHP/5.3.5
Access-Control-Allow-Origin: *
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 85
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/plain
X-Antivirus: avast! 4
X-Antivirus-Status: Clean
Mais ca ne marche pas mieux qu'avant

Citation:
Je n'ai jamais utilisé le Cross-domain, vous en savez maintenant plus que moi. Mais sur le forum PHP il y a sûrement quelqu'un de plus compétent sur ce sujet.
Je ne pense pas que ce soit un problème de PHP puisque j'ai les en-têtes attendues. C'est du côté du navigateur (plus que de jQUery même) que ça coince.

Citation:
Envoyé par Bovino Voir le message
Comme l'a déjà indiqué Daniel, crossDomain, qui ne s'applique qu'aux scripts permet de créer une balise script et de l'intégrer dans la page. Ce qui explique aussi l'impossibilité de mode synchrone puisque seuls les scripts rencontrés avant la fermeture du DOM sont chargés de façon synchrone.
D'accord je comprends mieux, merci pour la précision.
En l’occurrence, je travaille avec des fichiers ini donc pas de JSONP ou de <script/>. J'ai repassé crossDomain à false et je peux donc refaire du chargement synchrone mais j’obtiens les même messages que ceux évoqués dans mon premier post, retour à la case départ.
fanfouer est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/06/2011, 20h33   #11
Nouveau Membre du Club
 
Étudiant
Inscription : janvier 2008
Messages : 128
Détails du profil
Informations personnelles :
Localisation : France, Haute Savoie (Rhône Alpes)

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : janvier 2008
Messages : 128
Points : 34
Points : 34
Bien j'ai une solution à apporter

L'échange fonctionne maintenant normalement, j'ai du oublier de spécifier certains headers dans la réponse du serveur et probablement la méthode OPTIONS comme étant acceptée pour le cross-domain.

Pour rappel et pour ceux qui liront ce topic dans 250 ans, j'utilise le code suivant Javascript pour charger le contenu de mes fichiers ini de configuration de mon côté client (pour un autre format, modifier principalement la valeur de dataType) :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
 
$.ajax({
	async:false,
	crossDomain:false,
	url:url,
	method:"GET",
	success:function (data){
		file_details.content = data;
	},
	error:function (xhr, status, error){
		alert("Erreur de chargement du fichier '"+url+"' : "+xhr.responseText+" ("+status+" - "+error+")");
	},
	dataType:'text'
});
Lors de la requête, le scénario est un peu plus compliqué qu'une demande AJAX standart : il y a d'abord une requête preflight, puis une requête normale (pour évaluer la politique cross-domain du site visé).
La requête preflight est une HTTP/1.1 OPTIONS sur l'URL visée avec les en-têtes suivantes :
Citation:
Origin: http://sous-domaine.exemple.com
Access-Control-Request-Method: GET
Access-Control-Request-Headers: x-requested-with
La réponse est un HTTP 200 OK avec les données et les en-têtes qui intéressent le navigateur :
Citation:
Access-Control-Allow-Origin: http://sous-domaine.exemple.com
Access-Control-Allow-Methods: GET,OPTIONS
Access-Control-Allow-Headers: x-requested-with
Le navigateur compare donc ses infos avec celles du serveur et décide ou non d'envoyer une deuxième requête, GET cette fois, sans les en-têtes de contrôle d'accès. C'est à cet endroit que ça bloquait chez moi, merci wireshark.

Ensuite tout se passe suivant la méthode standard.

Vu que dans mon cas je souhaitait accéder à des fichiers binaires/text sans passer par PHP, voici le code définitif de mon proxy qui permet d'ajouter les en-têtes côté serveur :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 
header ("Access-Control-Allow-Origin:*", true);
header ("Access-Control-Allow-Methods: GET,OPTIONS", true);
header ("Access-Control-Allow-Headers: x-requested-with", true);
 
$file = $_GET["file"];
 
if (is_file ("./".$file.".ini")){
	header ("Content-Type:text/plain");
 
	readfile("./".$file.".ini");
 
 
}else{
	header ("HTTP/1.1 404 Not Found");
	echo "404";
}
A noter qu'il n'est pas possible de spécifier un Access-Control-Allow-Origin de la forme *.exemple.com. C'est bien dommage.

Merci à votre aide et bonne soirée
fanfouer est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 00h45.


 
 
 
 
Partenaires

Hébergement Web