Précédent   Forum des professionnels en informatique > Webmasters - Développement Web > JavaScript
JavaScript Forum programmation JavaScript. Lire : Cours JavaScript, FAQ JavaScript, Toutes les FAQ JavaScript et Sources 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 09/02/2011, 22h18   #1
Membre à l'essai
 
Inscription : novembre 2006
Messages : 121
Détails du profil
Informations forums :
Inscription : novembre 2006
Messages : 121
Points : 22
Points : 22
Par défaut fonction encapsulée dans des parenthèses ?

Bonjour,

Il y a une syntaxe javascript que j'ai un peu de mal à comprendre, et qu'on retrouve par exemple dans le code de suivi asynchrone de Google Analytics :

Code :
1
2
3
4
5
6
7
8
9
10
 
var _gaq=_gaq || [];
_gaq.push(['_trackPageview]);
 
(function() {
	console.log("analytics asynchrone function");
	var ga=document.createElement('script'); ga.type=text/javascript'; ga.async=true;
	ga.src=('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
	var s=document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
Il y a déclaration d'une fonction sans nom, encapsulées dans des parenthèses. Le code contenu à l'intérieur de la fonction est exécuté au chargement de la page (avant le DOM Ready).

Pourquoi dans ce cas, ne pas avoir écrit simplement :

Code :
1
2
3
4
5
6
7
8
 
var _gaq=_gaq || [];
_gaq.push(['_trackPageview]);
 
console.log("analytics asynchrone function");
var ga=document.createElement('script'); ga.type=text/javascript'; ga.async=true;
ga.src=('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s=document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
?

Merci
Galdon est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/02/2011, 23h14   #2
Modérateur
 
Avatar de NoSmoking
 
Homme
Inscription : janvier 2011
Messages : 2 930
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Isère (Rhône Alpes)

Informations forums :
Inscription : janvier 2011
Messages : 2 930
Points : 4 744
Points : 4 744
Bonsoir,
j'ai retrouvé le lien sur Les fonctions anonymes, sur ce site même.
Tout l'article, depuis le début, devrait répondre à toutes tes questions
NoSmoking est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/02/2011, 09h46   #3
Expert Confirmé Sénior
 
Avatar de RomainVALERI
 
Homme Romain VALERI
POOête
Inscription : avril 2008
Messages : 2 572
Détails du profil
Informations personnelles :
Nom : Homme Romain VALERI
Âge : 35
Localisation : France, Meurthe et Moselle (Lorraine)

Informations professionnelles :
Activité : POOête

Informations forums :
Inscription : avril 2008
Messages : 2 572
Points : 4 073
Points : 4 073
C'est vraisemblablement pour limiter la portée des variables utilisées et éviter d'éventuelles "collisions" avec les autres scripts de la page ^^
__________________

...pour les linguistes et les curieux >>> générateur de phrases aléatoires

__________________
RomainVALERI est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/02/2011, 10h49   #4
Membre Expert
 
Avatar de Willpower
 
Homme Boris Dessy
sans emploi
Inscription : décembre 2010
Messages : 847
Détails du profil
Informations personnelles :
Nom : Homme Boris Dessy
Localisation : Belgique

Informations professionnelles :
Activité : sans emploi

Informations forums :
Inscription : décembre 2010
Messages : 847
Points : 1 344
Points : 1 344
Citation:
Envoyé par RomainVALERI Voir le message
C'est vraisemblablement pour limiter la portée des variables utilisées et éviter d'éventuelles "collisions" avec les autres scripts de la page ^^
Effectivement la seule différence entre les 2 exemples c'est que dans le premier les variables ga et s n'existent plus une fois l'exécution la fonction finie. Et dans le cas où il existait déjà des variables de ce nom, elles ne sont pas écrasées.

Perso je commence tjs mes fichiers js par " (function(){" et les fini tjs par "})()"
Willpower est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/02/2011, 13h20   #5
Expert Confirmé Sénior
 
Avatar de RomainVALERI
 
Homme Romain VALERI
POOête
Inscription : avril 2008
Messages : 2 572
Détails du profil
Informations personnelles :
Nom : Homme Romain VALERI
Âge : 35
Localisation : France, Meurthe et Moselle (Lorraine)

Informations professionnelles :
Activité : POOête

Informations forums :
Inscription : avril 2008
Messages : 2 572
Points : 4 073
Points : 4 073
Citation:
Envoyé par Willpower Voir le message
Perso je commence tjs mes fichiers js par " (function(){" et les fini tjs par "})()"
Je ne l'ai jamais ni fait ni même envisagé mais je trouve le concept très bon, je crois que je vais m'y mettre
__________________

...pour les linguistes et les curieux >>> générateur de phrases aléatoires

__________________
RomainVALERI est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/02/2011, 14h28   #6
Responsable Développement Web

 
Avatar de Bovino
 
Homme Didier Mouronval
Développeur Web
Inscription : juin 2008
Messages : 13 805
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 805
Points : 35 810
Points : 35 810
Les choses qui vont sans dire allant toujours mieux en les disant, autant préciser que cette méthode implique de placer ses scripts en fin de page, juste avant la balise </body> et non pas dans le head
__________________
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 10/02/2011, 22h12   #7
Modérateur
 
Avatar de NoSmoking
 
Homme
Inscription : janvier 2011
Messages : 2 930
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Isère (Rhône Alpes)

Informations forums :
Inscription : janvier 2011
Messages : 2 930
Points : 4 744
Points : 4 744
Citation:
Envoyé par Bovino Voir le message
Les choses qui vont sans dire allant toujours mieux en les disant, autant préciser que cette méthode implique de placer ses scripts en fin de page, juste avant la balise </body> et non pas dans le head
on peut également prévoir que tout ne sera prêt et le traiter, exemple
Code :
1
2
3
4
5
6
7
8
9
10
11
12
(function(){
  function init(){
    var oDiv = document.getElementById('the_div');
    if( oDiv){
      oDiv.innerHTML = 'document charg&eacute;';
    }
    else{
      addEvent( window, "load", init, false);
    }
  }
  init();
})();
l'avantage pour l'utilisateur est qu'il n'a pas à ce préoccuper de l'endroit ou il inclus le script.
NoSmoking est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/02/2011, 23h36   #8
Membre à l'essai
 
Inscription : novembre 2006
Messages : 121
Détails du profil
Informations forums :
Inscription : novembre 2006
Messages : 121
Points : 22
Points : 22
Merci pour vos réposnes.

Citation:
Envoyé par Bovino Voir le message
Les choses qui vont sans dire allant toujours mieux en les disant, autant préciser que cette méthode implique de placer ses scripts en fin de page, juste avant la balise </body> et non pas dans le head
Je ne comprend pas, pourquoi faudrait il forcément placer les JS en bas de la page et pas dans le head quand on utilise cette technique de fonction anonyme/namespace ?

Soit le code est indépendant du DOM, et on l'exécute le plus tôt possible (déclaration de fonction, de tableaux, d'objets, initialisations diverses...), soit on a besoin du DOM et dans ce cas en encapsule le code dans une fonction genre jQuery(document).ready(), non ?
Galdon est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/02/2011, 10h26   #9
Membre Expert
 
Avatar de Willpower
 
Homme Boris Dessy
sans emploi
Inscription : décembre 2010
Messages : 847
Détails du profil
Informations personnelles :
Nom : Homme Boris Dessy
Localisation : Belgique

Informations professionnelles :
Activité : sans emploi

Informations forums :
Inscription : décembre 2010
Messages : 847
Points : 1 344
Points : 1 344
Citation:
Envoyé par Galdon Voir le message
Merci pour vos réposnes.



Je ne comprend pas, pourquoi faudrait il forcément placer les JS en bas de la page et pas dans le head quand on utilise cette technique de fonction anonyme/namespace ?

Soit le code est indépendant du DOM, et on l'exécute le plus tôt possible (déclaration de fonction, de tableaux, d'objets, initialisations diverses...), soit on a besoin du DOM et dans ce cas en encapsule le code dans une fonction genre jQuery(document).ready(), non ?
Effectivement , je pense que bovino devait être fatigué en postant sa remarque. Ca arrive même aux meilleurs.

Pour aller plus loin dans cette encapsulation de code. J'avais même penser à un moment de sauver les fonctions natives dans ma(mes) capsules et de supprimer leurs accès une fois toutes mes capsules définies. Cela bloquerait toutes tentatives d'attaques JS , qui avouons-le, sont quand même frequentes. Un peu dans ce genre-ci. ( bien que je ne l'ai jamais mis en œuvre ) : http://pastebin.com/bAekPv6a

Willpower est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/02/2011, 10h38   #10
Membre Expert
 
Avatar de Loceka
 
Tlouye Ci
Inscription : mars 2004
Messages : 1 450
Détails du profil
Informations personnelles :
Nom : Tlouye Ci

Informations forums :
Inscription : mars 2004
Messages : 1 450
Points : 2 149
Points : 2 149
Citation:
Envoyé par Willpower Voir le message
J'ai pas la possibilité de tester maintenant mais je suis convaincu qu'avec un javascript utilisateur c'est facilement contournable étant donné que les scripts utilisateurs sont lancés dès le début du chargement de la page. Il est donc possible d'empêcher ton code de s'exécuter ou, plus simplement, de se faire se propre binding avant ce script et de les restaurer par la suite.
Loceka est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/02/2011, 11h08   #11
Membre Expert
 
Avatar de Willpower
 
Homme Boris Dessy
sans emploi
Inscription : décembre 2010
Messages : 847
Détails du profil
Informations personnelles :
Nom : Homme Boris Dessy
Localisation : Belgique

Informations professionnelles :
Activité : sans emploi

Informations forums :
Inscription : décembre 2010
Messages : 847
Points : 1 344
Points : 1 344
Citation:
Envoyé par Loceka Voir le message
J'ai pas la possibilité de tester maintenant mais je suis convaincu qu'avec un javascript utilisateur c'est facilement contournable étant donné que les scripts utilisateurs sont lancés dès le début du chargement de la page. Il est donc possible d'empêcher ton code de s'exécuter ou, plus simplement, de se faire se propre binding avant ce script et de les restaurer par la suite.
Ouais ça dépend du type d'attaques bien sur. Mais en mettant directement ce.code dans le header. On pourrait éviter les attaques par url (javascript:...) et si ya un script dans le body (par exemple une injection via un profil ) il ne pourra non plus pas être exécuté si celui du head l'a précédé. Ça reste conceptuel vu que je ne pense pas que ça soit déjà mis en œuvre. Mais je reste convaincu de l'efficacité que ça pourrait avoir niveau protection des attaques js.
Willpower est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/02/2011, 04h13   #12
Membre Expert
 
Avatar de Willpower
 
Homme Boris Dessy
sans emploi
Inscription : décembre 2010
Messages : 847
Détails du profil
Informations personnelles :
Nom : Homme Boris Dessy
Localisation : Belgique

Informations professionnelles :
Activité : sans emploi

Informations forums :
Inscription : décembre 2010
Messages : 847
Points : 1 344
Points : 1 344
UP:
Voila, une version d'usage hyper facile de ma protection totale de JS :
http://pastebin.com/eUVaSu4V



(ce n'est qu'un exemple, il n'y a encore que alert qui est vraiment protégé.)
mais l'usage est vraiment ultra simple :

inclure un fichier secure_0 qui crée simplement un objet :
Code js :
var secure = {s:"var alert = window.alert, document_getElementById = document.getElementById, d = {}; d.getElementById = function(){var r = document_getElementById.apply(document,arguments);return r;};",u:function(){},f:function(){	window.alert = this.u; document.getElementById = this.u;}};

encapsuler tous ses autres fichiers JS en les commençant par :
Code js :
(function(){eval(secure.s);
et en les terminant par :

une fois tous les JS encapsulés, finir par le fichier secure_1 qui appelle simplement la fonction de suppression :

Et pour moi, si vous incluez tout ça dans le header, la protection est vraiment top.
Bon, comme le dit Loceka, ça ne protège pas des script utilisateur (par exemple une fonction JS qui fixe une limite de char dans un textarea, l'utilisateur peut le bloquer, mais ce genre de chose doit de toute façon être vérifié du coté serveur et ne pourra jamais être empêché du coté client car le client peut envoyer les données qu'il veut au serveur sans même utiliser un navigateur.) Cette technique protégerait contre les "vraies" attaques JS du genre celles qui s’exécute chez un visiteur contre son gré pour lui voler ses cookies par exemple. (soit en passant par l'url : javascript:alert(document.cookie);, soit avec une injection via une page : par exemple un profil).

Perso, je trouve que ça a du potentiel énorme et que je devrais le développer et le publier.

edit: version online (vous ne pouvez pas faire de "alert" ni de "document.getElementById" mais la page a toujours accès a ces fonctions via des variables locales encapsulés.)
http://ulb.comli.com/secure.html

edit2: évidement faut faire gaffe, car comme l'auront remarqué ceux qui utilise IE (haha^^) après le document.onload, IE execute encore de son plein gré la fonction "onresize" qui elle même(lors de son premier appel. Il ne faut pas chercher à comprendre IE, ça me ferait trop peur) appelle "document.getElementById". (qu'on a supprimé) et donc IE est pas content content !

edit:3 faudra jusque que je prévois une fonction supplémentaire de chargement + encapsulation dynamique des script. autrement ils n'auront pas accès aux fonctions. Cette fonction qui ne pourra évidement être appelée qu'à partir d'une capsule existante pour garantir la sécurité.
Willpower est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 14/02/2011, 09h21   #13
Membre Expert
 
Avatar de Loceka
 
Tlouye Ci
Inscription : mars 2004
Messages : 1 450
Détails du profil
Informations personnelles :
Nom : Tlouye Ci

Informations forums :
Inscription : mars 2004
Messages : 1 450
Points : 2 149
Points : 2 149
Citation:
Envoyé par Willpower Voir le message
edit2: évidement faut faire gaffe, car comme l'auront remarqué ceux qui utilise IE (haha^^) après le document.onload, IE execute encore de son plein gré la fonction "onresize" qui elle même(lors de son premier appel. Il ne faut pas chercher à comprendre IE, ça me ferait trop peur) appelle "document.getElementById". (qu'on a supprimé) et donc IE est pas content content !
Du coup tout le moteur JS part en vrille ?
Au pire il suffit de réécrire la fonction onresize pour qu'elle ne fasse rien. ^_^
Loceka est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/02/2011, 11h19   #14
Membre Expert
 
Avatar de Willpower
 
Homme Boris Dessy
sans emploi
Inscription : décembre 2010
Messages : 847
Détails du profil
Informations personnelles :
Nom : Homme Boris Dessy
Localisation : Belgique

Informations professionnelles :
Activité : sans emploi

Informations forums :
Inscription : décembre 2010
Messages : 847
Points : 1 344
Points : 1 344
Citation:
Envoyé par Loceka Voir le message
Du coup tout le moteur JS part en vrille ?
Au pire il suffit de réécrire la fonction onresize pour qu'elle ne fasse rien. ^_^
Non. Y'a juste un averto dans la console quand je met "document.getElementById = null" disant que cette fonction n'existe pas.mais pas de problème quand je remplace par "document.getElementById = function(){};" mais je me dis que ça pourrait poser problème pour d'autres méthodes si IE se met à exécuter du js (redéfinissable) de son plein gré.
Willpower est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/02/2011, 11h54   #15
Expert Confirmé Sénior
 
Avatar de RomainVALERI
 
Homme Romain VALERI
POOête
Inscription : avril 2008
Messages : 2 572
Détails du profil
Informations personnelles :
Nom : Homme Romain VALERI
Âge : 35
Localisation : France, Meurthe et Moselle (Lorraine)

Informations professionnelles :
Activité : POOête

Informations forums :
Inscription : avril 2008
Messages : 2 572
Points : 4 073
Points : 4 073
Allez les gars un petit effort, faites-nous un nouveau browser, vous êtes plus très loin
__________________

...pour les linguistes et les curieux >>> générateur de phrases aléatoires

__________________
RomainVALERI est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/02/2011, 16h59   #16
Membre Expert
 
Avatar de Willpower
 
Homme Boris Dessy
sans emploi
Inscription : décembre 2010
Messages : 847
Détails du profil
Informations personnelles :
Nom : Homme Boris Dessy
Localisation : Belgique

Informations professionnelles :
Activité : sans emploi

Informations forums :
Inscription : décembre 2010
Messages : 847
Points : 1 344
Points : 1 344
Citation:
Envoyé par RomainVALERI Voir le message
Allez les gars un petit effort, faites-nous un nouveau browser, vous êtes plus très loin
J'y suis presque, j'en suis déjà à faire des
Code js :
eval('eval("....");');
(pour l'instant je n'ai jamais vu un eval indispensable dans un code, les 2 ici servent juste à éviter de la duplication de code et donc à faciliter l'écriture et l'appel de mes fonctions.)
et des
Code js :
function(){return function(){return function(){... }}};
un double return fonction
le premier servant à sauvergarder des variables qui n'existeront plus lors de l'execution du second.(appelé une fois au début)
le second servant à recréer une nouvelle fonction différente à chaque appel. (appelé plusieurs fois en fin)

et sinon en remontant les "caller" j'ai identifié les fonctions que IE execute après l'initialisation de la page. (après même l'éxecution de notre code du window.onload).

appelée elle-même par :

appelée elle-même par :


arg.... javascript me rend complètement cinglé !



Code html :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<!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">
 
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Test JS secure</title>
<!-- <script type="text/javascript" src="secure_0.js"></script> -->
<!-- <script type="text/javascript" src="jquery.js"></script> -->
<!-- <script type="text/javascript" src="myOwnFunctions.js"></script> -->
<!-- <script type="text/javascript" src="secure_1.js"></script> -->
<script type="text/javascript">
 
// SAMPLES SECURE #0 : secure_0.js
var secure = {s:"var w=['alert','back','blur','captureEvents','clearInterval','clearTimeout','close','confirm','disableExternalCapture','enableExternalCapture','find','focus','forward','handleEvent','home','moveBy','moveTo','open','print','prompt','releaseEvents','resizeBy','resizeTo','routeEvent','scroll','scrollBy','scrollTo','setInterval','setTimeout','stop','toSource','toString','unwatch','valueOf','watch'];for(var i in w) if(window[w[i]]!=undefined) eval('var '+w[i]+' = window[w[i]];');var document_getElementById = document.getElementById, d = {}; d.getElementById = function(){var r = document_getElementById.apply(document,arguments);return r;};",u:(function(){var alert=window.alert; return function(){return function(){if(typeof(window.wpaCommon)!="undefined" && wpaCommon.onPageLoaded==arguments.callee.caller)return;alert("[Security] You can't do it !");}; };})(),f:function(){var alert=window.alert;	window.alert = this.u(); document.getElementById = this.u();}};
 
 
// SAMPLES OF JS FILE #1 : jquery.js
(function(){eval(secure.s);
 
	// ----------
	// past all jQuery code here
	// ----------
})();
 
 
// SAMPLES OF JS FILE #2 : myOwnFunctions.js
(function(){eval(secure.s);
 
	// sample to use secure functions  
	window.onload = function(){
		d.getElementById("tt").onclick=function(){alert("d.getElementById('tt') : "+d.getElementById("tt"));this.innerHTML+="<br/>tayooooo";};  
	};
 
})();
 
 
 
// SAMPLES SECURE #1 : secure_1.js
secure.f();
 
</script>
</head>
 
<body>
 
	try to alert my span with id "tt", write in address url : <br/>
	<a href=javascript:alert(1);>javascript:alert(1);</a> // secure <br/>
	<a href=javascript:document.getElementById('tt'); >javascript:document.getElementById('tt');</a> // secure<br/>
	then <span id='tt'><b>CLICK HERE</b></span> and you'll see as the "alert" AND the "getElementById" are still working ... only protected from you^^
 
</body>
 
</html>
Willpower est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/02/2011, 20h30   #17
Expert Confirmé Sénior
 
Avatar de RomainVALERI
 
Homme Romain VALERI
POOête
Inscription : avril 2008
Messages : 2 572
Détails du profil
Informations personnelles :
Nom : Homme Romain VALERI
Âge : 35
Localisation : France, Meurthe et Moselle (Lorraine)

Informations professionnelles :
Activité : POOête

Informations forums :
Inscription : avril 2008
Messages : 2 572
Points : 4 073
Points : 4 073
Citation:
Envoyé par Willpower Voir le message
arg.... javascript me rend complètement cinglé !
Ce soir chez Boris c'est..... soirée disco !
__________________

...pour les linguistes et les curieux >>> générateur de phrases aléatoires

__________________
RomainVALERI est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 11h34.


 
 
 
 
Partenaires

Hébergement Web