Affichage des articles dont le libellé est Javascript. Afficher tous les articles
Affichage des articles dont le libellé est Javascript. Afficher tous les articles

mercredi 20 octobre 2010

How to host files on Google (javascript, css, html, ...) and get a permanent, non-redirecting and bandwidth-generous hotlink

What is the point of hosting such files on Google and not on another server?

I think this question needs no response, the purpose is to take advantage of the very generous bandwidth of Google to display our html or our images, to load our scripts or css stylesheets.
After a long search for the miraculous solution, and after having tested everything: Google sites, Google docs, javascript and css encapsulations on images, ...etc I finally found the ultimate solution.

In fact the two solutions Google sites and Google docs are not permanent, since the links to the files change from time to time, such that we find ourselves forced to update the source code of our site each day! Also, the links used make redirections, which translates into a larger load times for our pages.

The solution of encapsulated script (hidden) in an image is also not very clean, in fact I noticed a big slowdown in the browser when evaluating a heavy script with eval() function.

The final solution is to use Google Code to store files and get a direct link (without redirection, permanent, and mainly mime-typed ). Here's how it can be done:

  1. Create your Google Code project:


    Go to http://code.google.com/hosting and click Create a new project, give a name, a summary and a description to the project, then choose Subversion in Version control system and anything in Source code license then click on Create project button, once the project is created, you will find yourself in the Project Management page, go to the Source tab and note the link of the project directory, it will look like this: https://ubugnu.googlecode.com/svn/trunk/ and will be next to svn checkout.
    To be able to put files in that directory you will need a password (otherwise anyone can tinker with your project), to get the password click googlecode.com password just below the link, note also that password.

  2. Connect to the project via svn and host files on Google by synchronizing the project directory with a local directory


    We will need the subversion package, install it with:
    ubugnu@ubugnu-laptop:~$ sudo apt-get install subversion
    Once the package is installed, here is what we'll do: Create a local directory which will be an exact copy the project directory and which you can synchronize at any time, ie edit the files locally, then synchronize the files so that Google files are also modified. That's how you create a copy of the project directory:
    ubugnu@ubugnu-laptop:~$ svn checkout "https://ubugnu.googlecode.com/svn/trunk/" ubugnu
    This command will create a directory called ubugnu which is an exact copy of that which is on the server, and as it is empty, my local directory will also be so.
    We will add a file (eg javascript) in our local directory then "spread" the change to the Google server, for example:
    ubugnu@ubugnu-laptop:~$ cd ubugnu
    ubugnu@ubugnu-laptop:~$ touche test.js
    ubugnu@ubugnu-laptop:~$ cp /var/www/test.js ./test.js
    ubugnu@ubugnu-laptop:~$ svn add ./test.js
    We will need to link to svn a text editor, nano would be best suited:
    ubugnu@ubugnu-laptop:~$ export SVN_EDITOR=nano
    You can put your favorite editor instead of nano (eg gedit)
    Now that our local directory ubugnu has been changed, one must propagate this change to the server with:
    ubugnu@ubugnu-laptop:~$ svn commit ./test.js --username ubugnu
    I put my Google nickname (put yours, it is the one contained in your gmail email address)
    A page will then appear in the text editor that you previously selected, save (Ctrl+o) and quit (Ctrl+x), then type the letter "c" (continue to) in the terminal and press enter.
    The terminal will then ask you the password of the administrator (root), type it, then it will ask for the password to access the project directory on Google, type the one you noted earlier and submit. Bravo, the file has been placed on the Google server.
    To check, click the Source then Browse and finally Trunck links, you'll see the file test.js, click it, then in the page that appears click on view raw file at the bottom right. The link you get is the one you can use in your source codes, it is quick and permanent.

    Go back and notice that the MIME-type file is text/plain (below view raw file) that is plain text, which is not a problem for a javascript file but can affect interpretation of other extensions (css for example)

  3. Changing the mime-type of files depending on their format:


    So as I said, mime-type can be problematic when it comes to files for which the browser checks the mime-type, try for example a css file on the server and include it in a page you will see that it will have no effect (it will not be interpreted) because its mime-type is the default text/plain, so we must change it.

    For our example, we will not use a css file but an html file, create an html file locally and put in a little html code:
    ubugnu@ubugnu-laptop:~$ touch test.html
    ubugnu@ubugnu-laptop:~$ nano test.html
    And put
    <html> 
    <body>
    <h2>it works</h2>
    </body>
    </html>
    Now we propagate the change with commit
    ubugnu@ubugnu-laptop:~$ svn commit ./test.html --username ubugnu
    We go as earlier to Source::Browse::trunck and click on test.html, then on view raw file and we note that the page appears in source code, meaning that the browser has not parsed the html code, simply because it considers the file as raw text because its mime-type is text/plain.
    Here is how to fix this:
    ubugnu@ubugnu-laptop:~$ svn propset svn:mime-type text/html ./test.html
    then propagate againe
    ubugnu@ubugnu-laptop:~$ svn commit ./test.html --username ubugnu
    Refresh the page test.html, you will see that the code is now parsed (Here is an example) :-)
    if we had wanted to host for example a css file, it should have been
    ubugnu@ubugnu-laptop:~$ svn propset svn:mime-type text/css ./test.css

Hébergement de fichiers texte, javascript, css, html ou autre sur Google

Quelle est l'utilité d'héberger de tels fichiers sur Google et non pas sur un autre serveur?

Je crois que cette question n'a pas besoin de réponse, l'utilité est qu'on profite de la très généreuse bande passante de Google afin d'afficher nos pages html ou nos images, de charger nos scripts javascript ou nos feuilles de style css.
Après une longue recherche de la solution miraculeuse, et après avoir tout testé: Google sites, Google docs, encapsulation de script javascript et feuille de style css dans une image, ...etc j'ai fini par trouver la solution ultime.

En effet les deux solutions Google sites et Google docs ne sont pas permanentes, vu que les liens vers les fichiers changent de temps en temps, résultat on se retrouve forcé de mettre à jour le code source de notre site chaque jour! Ce qui n'est pas très pro. Aussi, les liens utilisés font une redirection, ce qui se traduit par un temps de chargement plus grand pour nos pages.

La solution du code encapsulé (caché) dans une image est quant à elle pas très propre, en effet j'ai remarqué un grand ralentissement du navigateur au moment de l'évaluation d'un code lourd avec la fonction eval().

La solution finale est donc d'utiliser Google code pour stocker ses fichiers et avoir un lien direct (sans redirection, permanent et surtout mime-typé). Voici comment on fait:

  1. Créer son projet Google code:


    Allez à la page http://code.google.com/hosting et cliquez sur Create a new project, donnez un nom, un sommaire et une description au projet, puis choisissez Subversion dans Version control system et n'importe quoi dans Source code license puis appuyez sur le bouton Create project, une fois le projet créé, vous vous retrouverez dans la page de gestion du projet, allez dans l'onglet Source et notez le lien du répertoire du projet, il ressemblera à ceci: https://ubugnu.googlecode.com/svn/trunk/ et se trouvera juste après svn checkout.
    Pour pouvoir mettre des fichiers dans ce répertoire vous aurez besoin d'un mot de passe (sinon n'importe qui pourra bricoler dans votre projet), pour avoir ce mot de passe cliquez sur googlecode.com password juste en dessous du lien, notez aussi ce mot de passe.

  2. Se connecter au projet via svn et héberger ses fichiers sur Google en synchronisant le répertoire du projet avec un répertoire local


    On aura besoin du paquet subversion, installez le avec:
    ubugnu@ubugnu-laptop:~$ sudo apt-get install subversion
    Une fois le paquet installé, voila ce qu'on va faire: créer un répertoire local qui sera la copie conforme du répertoire du projet et qu'on pourra synchroniser à tout moment, c'est à dire modifier les fichiers en local, et après synchroniser pour que les fichiers sur Google soient aussi modifiés. Voila comment on crée une copie du répertoire du projet:
    ubugnu@ubugnu-laptop:~$ svn checkout "https://ubugnu.googlecode.com/svn/trunk/" ubugnu
    Cette commande va me créer un répertoire nommé ubugnu qui sera l'exacte copie de celui sur le serveur, et comme ce dernier est vide, mon répertoire local le sera aussi.
    On va ajouter un fichier (par exemple javascript) dans notre répertoire local pour après le "propager" vers le serveur de Google, par exemple:
    ubugnu@ubugnu-laptop:~$ cd ubugnu
    ubugnu@ubugnu-laptop:~$ touche test.js
    ubugnu@ubugnu-laptop:~$ cp /var/www/test.js ./test.js
    ubugnu@ubugnu-laptop:~$ svn add ./test.js
    Nous aurons besoin d'associer à svn un éditeur de texte, par exemple nano serait le mieux adapté:
    ubugnu@ubugnu-laptop:~$ export SVN_EDITOR=nano
    Vous pouvez mettre votre éditeur préféré à la place de nano (par exemple gedit)
    Maintenant que notre répertoire local ubugnu a été modifié, on doit propager cette modification vers le serveur avec:
    ubugnu@ubugnu-laptop:~$ svn commit ./test.js --username ubugnu
    ou j'ai mis mon pseudo Google (mettez à sa place le votre, c'est celui contenu dans votre adresse email gmail)
    Une page s'affichera alors dans l'éditeur de texte que vous aviez préalablement choisis, sauvegardez là et quittez, puis tapez la lettre "c" (pour continue) dans le terminal et validez.
    Le terminal vous demandera alors le mot de passe de l'administrateur (root), tapez le, alors il vous demandera le mot de passe d'accès au répertoire du projet sur Google, tapez celui que vous avez noté tout à l'heure et validez. Bravo, le fichier vient d'être mis sur le serveur de Google.
    Pour le vérifier, cliquez sur l'onglet Source puis sur Browse et enfin sur trunck, vous verrez le fichier test.js, cliquez dessus, puis dans la page qui s'affiche clqiuez sur view raw file en bas à droite. Le lien que vous obtiendrez est celui que vous pourrez utiliser dans vos codes sources, il est rapide et permanent.

    Revenez en arrière et remarquez que le mime-type du fichier est text/plain (en dessous du lien view raw file) c'est à dire du texte brute, ce qui n'est pas un problème pour un fichier javascript mais peut l'être pour d'autres extensions (css en l'occurrence)

  3. Changer le mime-type des fichiers selon leur format:


    Donc comme je l'ai dis, le mime-type peut être problématique quand il s'agit de fichiers pour lesquels le navigateur vérifie le mime-type, essayez par exemple de mettre un fichier css sur le serveur et de l'inclure dans une page, vous verrez qu'il n'aura aucun effet car son mime-type est par défaut text/plain, il faudra le changer.

    Pour notre exemple, on ne va pas utiliser un fichier css mais un fichier html, créons un fichier html en local et mettons y un peu de code html:
    ubugnu@ubugnu-laptop:~$ touch test.html
    ubugnu@ubugnu-laptop:~$ nano test.html
    et on met

    <html>
    <body>
    <h2>it works</h2>
    </body>
    </html>
    Maintenant on propage cette modification avec commit
    ubugnu@ubugnu-laptop:~$ svn commit ./test.html --username ubugnu
    On va comme tout à l'heure dans l'onglet Source::Browse::trunck et on clique sur test.html, on clique après sur view raw file et on remarque que la page apparait en code source, c'est à dire que le navigateur n'a pas parsé le code html, simplement parce qu'il considère le fichier comme du texte brute car son mime-type est texte/plain.
    Voici donc comment réparer cela:
    ubugnu@ubugnu-laptop:~$ svn propset svn:mime-type text/html ./test.html
    puis on repropage
    ubugnu@ubugnu-laptop:~$ svn commit ./test.html --username ubugnu
    Actualisez la page test.html, vous verrez que le code est maintenant parsé (voici un exemple) :-)
    Si on avait par exemple voulu héberger du css, on aurait dû faire
    ubugnu@ubugnu-laptop:~$ svn propset svn:mime-type text/css ./test.css

jeudi 26 août 2010

Faire du cross-domain simplement avec javascript

Voilà, après un longue absence et une promesse que j'ai faite à SecDZ (que je ne suis pas sûr pouvoir arriver à tenir ;-)) je reviens pour vous parler de comment faire des requêtes cross-domain avec du code javascript très simple et sans attendre l'arrivée des nouvelles générations de XMLHttpRequest (Level 2).

Le cross-domaine simplement expliqué: Il s'agit de pouvoir faire des requêtes vers le site siteB.com à partir de code javascript chargé dans le navigateur à partir d'un site siteA.com.Il existe bien la méthode AJAX, mais qui ne permet de faire que des requêtes vers le même site (pour des questions évidentes de sécurité).Faisons un test grandeur nature, notre siteA.com est mon site ubuntudz.com et le site vers lequel on va faire des requêtes est ubugnu.com, le script javascript de cette page (émanant de siteA.com) doit être capable de faire des requêtes vers siteB.com et faire des modifications sur cette page suivant la réponse de siteB.com.

 +  =   

Dans cet exemple, javascript va faire une requête vers un autre site (siteB.com) et récupérer le résultat de l'addition, puis l'afficher dans la case adéquate, et ce sans passer par AJAX, car avec AJAX on n'aurait pu faire cette opération (erreur)Cette astuce est utile quand on veut profiter de la bande passante de Blogger par exemple pour le coté statique du site, et déléguer les tâches dynamique pour un autre site moins généreux en bande passante.Maintenant voila les scripts JS et PHP, le truc, c'est de créer une fonction JS qui inclut des codes JS, le serveur répondra par du vrai code JS selon les paramètres passés.


<script>
function include(src) {
var html_doc = document.getElementsByTagName('head').item(0);
var js = document.createElement('script');
js.src = src;
js.type = 'text/javascript';
js.defer = true;
html_doc.appendChild(js);
}
function cal(a,b) {
include("http://www.ubugnu.com/ubuntudz/?a="+a+"&b="+b);
}
</script>

<input id='a' style='width:20'> + <input id='b'' style='width:20'> = <input id='c'' style='width:20'> <input type='submit' onClick='cal()' value='calculer'>

<?
echo "document.getElementById('c').value=";
echo $_GET['a']+$_GET['b'].";";
?>

lundi 3 mai 2010

[Javascript] Encapsuler du javascript, du css et des images dans une seule et même image

Bonjour,
Il y'a quelques mois j'ai eu besoin d'encapsuler tout mes scripts, css et images dans une seul image, puis appeler cette image avec AJAX, et extraire le tout pour l'insérer dans le document. Je ne sais pas si ça va servir mais c'est intéressant de voir que ça marche ;-)


Donc, pour le tester, créez un dossier sur un serveur, mettez tout vos scripts, css et images (vous pouvez les mettre à la racine, dans des dossiers,...etc comme vous voulez), éventuellement numérotez vos scripts 1.js, 2.js, ... etc au cas ou l'un doit être inclus avant l'autre.
Mettez dans la racine du dossier une image nommée js.png, c'est elle qui va intégrer les scripts et les css.Mettez dans la racine du dossier ce script PHP:

<?
// embed images as data:image/gif;base64,...
function read_from_file ($file) {
$handle = @fopen($file, "r");
$data = '';
if ($handle) {
while (!feof($handle)) {
$buffer = fgets($handle, 4096);
$data .= $buffer;
}
fclose($handle);
}
return rtrim($data);
}
function write_to_file ($file, $data) {
$fp = fopen($file, "w");
fwrite($fp, $data);
fclose($fp);
}
function lReplace($m) {
echo " : image ".$GLOBALS['dn'].'/'.$m[1].'.'.$m[3]." base64 encoded in".$GLOBALS['fn']."<br>";
return "data:image/gif;base64,".base64_encode(read_from_file($GLOBALS['dn'].'/'.$m[1].'.'.$m[3]));
}
function lParse($dirname,$file) {
$GLOBALS['dn'] = $dirname;
$GLOBALS['fn'] = $dirname."/".$file;
$path = $dirname."/".$file;
$data = read_from_file($path);
write_to_file($path,preg_replace_callback('/([^\'\(\."\s]*)(\.)(gif|jpg|bmp|png)/i',lReplace,$data));
}
function read_dir1($dirname,$i) {
$j=$i+1;
$ind="";
while($i) {$ind .= '__';$i--;}
if (is_dir($dirname))
$dir_handle = opendir($dirname);
if (!$dir_handle)
return false;
while($file = readdir($dir_handle)) {
if ($file != "." && $file != "..") {
if (!is_dir($dirname."/".$file)) {
echo $ind.$dirname."/".$file."<br>";
if(preg_match('/.(\.)(css|js)/',$file)) {lParse($dirname,$file);}
}
else
read_dir1($dirname.'/'.$file,$j);
}
}
closedir($dir_handle);
return true;
}
read_dir1('.',0);


// embed css and js in an image
function store($d,$f) {
if(preg_match('/.(\.)(js)$/',$f)) $GLOBALS['data_js'] .= read_from_file($d."/".$f);
if(preg_match('/.(\.)(js)$/',$f)) $GLOBALS['data_js'] .= "\n\n";
if(preg_match('/.(\.)(css)$/',$f)) $GLOBALS['data_css'] .= read_from_file($d."/".$f);
if(preg_match('/.(\.)(css)$/',$f)) $GLOBALS['data_css'] .= "\n\n";
}
$ord = 1;

if($ord) {
function reador_dir($dirname,$i,$max) {
$j=$i+1;
$ind="";
while($i) {$ind .= '__';$i--;}
if (is_dir($dirname))
$dir_handle = opendir($dirname);
if (!$dir_handle)
return false;
while($file = readdir($dir_handle)) {
if ($file != "." && $file != "..") {
if (!is_dir($dirname."/".$file)) {
if(preg_match('/(\d){1,2}(\.)(js)$/',$file,$m) && $m[1]>$max) {$max=$m[1];}
}
else
$max = reador_dir($dirname.'/'.$file,$j,$max);
}
}
closedir($dir_handle);
return $max;
}

function storord($dirname,$i) {
if (is_dir($dirname))
$dir_handle = opendir($dirname);
if (!$dir_handle)
return false;
while($file = readdir($dir_handle)) {
if ($file != "." && $file != "..") {
if (!is_dir($dirname."/".$file)) {
if(preg_match("/$i(\.)(js)$/",$file)) {store($dirname,$file);echo "store($dirname/$file)<br>";}
}
else
storord($dirname.'/'.$file,$i);
}
}
closedir($dir_handle);
return false;
}

echo "max is ".reador_dir('.',0,1)."<br>";
$i=1;
while($i<reador_dir('.',0,1)+1) {storord('.',$i); $i++;}
}
function read_dir2($dirname,$i,$ord) {
$j=$i+1;
$ind="";
while($i) {$ind .= '__';$i--;}
if (is_dir($dirname))
$dir_handle = opendir($dirname);
if (!$dir_handle)
return false;
while($file = readdir($dir_handle)) {
if ($file != "." && $file != "..") {
if (!is_dir($dirname."/".$file)) {
if(preg_match('/.(\.)(css|js)$/',$file) && !$ord) {store($dirname,$file);echo "store($dirname/$file)<br>";}
elseif(preg_match('/.(\.)(css|js)$/',$file) && !preg_match('/(\d){1,2}(\.)(css|js)$/',$file)) {store($dirname,$file);echo "store($dirname/$file)<br>";}
}
else
read_dir2($dirname.'/'.$file,$j,$ord);
}
}
closedir($dir_handle);
return true;
}
read_dir2('.',0,$ord);
write_to_file ("js.png", read_from_file("js.png")."\n[JS]".$GLOBALS['data_js']."\n[CSS]".$GLOBALS['data_css']);
?>
Lancez ce script PHP, vous remarquerez qu'a la fin la taille de l'image aura considérablement augmenté, maintenant, dans la page qui doit inclure ce que vous avez encapsulé dans l'image, mettre le code javascript suivant:

<script>

function get_js (url) {
var request = false;
if(window.XMLHttpRequest) {
request = new XMLHttpRequest();
if(request.overrideMimeType) {
request.overrideMimeType('text/xml');
}
} else if(window.ActiveXObject) {
var versions = ['Microsoft.XMLHTTP', 'MSXML.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.7.0', 'Msxml2.XMLHTTP.6.0', 'Msxml2.XMLHTTP.5.0', 'Msxml2.XMLHTTP.4.0', 'MSXML2.XMLHTTP.3.0', 'MSXML2.XMLHTTP'];
for(var i=0; i<versions.length; i++) {
try {
request = new ActiveXObject(versions[i]);
} catch(e) {}
}
}
xmlHttpReq = request;
xmlHttpReq.open("GET",url, false);
//xmlHttpReq.onload = load_image(xmlHttpReq.responseText);
xmlHttpReq.send(null);
return xmlHttpReq.responseText;
}

function ress(resp,type) {
var b1 = resp.indexOf('[JS]') + 4;
var b2 = resp.indexOf('[CSS]') + 5;
var delb = b2-b1-5;
if(type=="js") return resp.substr(b1,delb);
if(type=="css") return resp.substring(b2);
}

var resp = get_js('js.png','js');
var html_doc = document.getElementsByTagName('head').item(0);
var js = document.createElement('script'); js.textContent = ress(resp,'js'); html_doc.appendChild(js);
var sty = document.createElement('style'); sty.textContent = ress(resp,'css'); html_doc.appendChild(sty);
</script>
Voila, maintenant vous pouvez utiliser le javascript et le css avec les images comme si vous l'avez inclue directement.
J'espère que j'ai été claire :-)