Libisemi, tvorba bookmarkletu podruhé


Minule jsem popsal způsob vytvoření bookmarkletu a částečně řídicí a zobrazující (odpovídající) logiku na straně serveru s tím, že se nejdená o finální řešení a má svoje mouchy. Tyto mouchy jsem vychytal a vyzkoušel opravené řešení v praxi a zjistil, že jsem zapomněl na poměrně podstatnou věc – zabezpečení a neumožnění croos domain AJAX požadavků, alespoň u slušných prohlížečů: stávající skript totiž přidal k cizí stránce můj kus kódu, který se snažil připojit na můj (=cizí) server. Takže jsem si naběhl a končil na výjimce "Access to restricted URI denied" code: "1012" nsresult: "0x805303f4 (NS_ERROR_DOM_BAD_URI)". Když už jsem ale minule slíbil pokračování stávajícího způsobu, dokončím popis a potom se pokusím problém vyřešit nejjednodušším možným způsobem.

Protože je člověk od přírody tvor lenošný a já nedělám výjimku svému druhu, nechtělo se mi hrát si httpRequestem a ručně dolaďovat bezpečnostní chybky, optimalizovat… Vzal jsem si proto na pomoc js framework jQuery, který Ajax zvládá za mě a věřím tomu, že mnohem lépe a efektivněji. Hned jsem tímto přístupem zabil dvě mouchy jednou ranou: první moucha je zmíněna na předchozím řádku (nebo spíše hejno much) a ta druhá – v původní verzi bookmarklet fungoval až po druhém kliknutí, což je samozřejmě neomluvitelné. Tuším, že je to způsobeno tím, že při prvním klepnutí se sice skript připojí k dokumentu, ale volané metody se neprovedou s tím, že jsou momentálně neznámé. Divné, ale je tomu tak, po druhém klepnutí na bookmarklet je už všechno v pořádku. Stačí samozřejmě na konec vkládaného skriptu vložit volání potřebných rutin a při jeho přiložení k dokumentu se okamžitě provedou.

javascript:
    void((
        function(){
            var element=document.createElement('script');
            element.setAttribute('src','http://www.libisemi.cz/send.js?i='+new Date().getTime());
            document.body.appendChild(element);
        })()
    )

Stejným způsobem využívám i nové volání pomocí jQuery, které zveřejňuji na následujícím výpise. Do dokumentu pomocí bookmarkletu vkládám tento skript (viz. výše) a zároveň i komprimovanou verzi knihovny jQuery, která se nachází v tomtéž souboru, takže stačí jedno klepnutí na bookmarklet a na lokálním stroji vše funguje jako švýcarské hodinky. Co se týká obsahu bookmarkletu, oproti minulé verzi tam přibyl "parametr" getTime(). Ten je tam proto, aby prohlížeč vzal v potaz změny ve skriptu send.js a nenačítal jej z cache; s getTime() je totiž požadovaná adresa vždy jedinečná, čili načítána znovu.

 /*
 * jQuery JavaScript Library v1.3.1
 * http://jquery.com/
 *
 * zde je vložená komprimovaná verze jQuery knihovny
 */

var u=encodeURIComponent(location.href);

$.ajax({
    type: "POST",
    url: 'http://www.libisemi.cz/addajax',
    data: 'url='+u,
    success: function(s){
        . . .
        window.location = "http://www.libisemi.cz/addform/"+id;
        . . .
    }
});

 V tomto případě ovšem pořád přetrvává výše zmíněná chyba z důvodu cross site requestů. Stačí chybu nacpat do googlu a pár řešení vyjede. Našel jsem ovšem efektivnější možnost posílání url a to tak, jak jsem původně chtěl, takže směle skvěle se vrhnu do něj, je to jednodušší a hlavně pohodlnější, než několik skriptů a využívání třeba JSONu.

edit: Chyba lávky! Ještě jednodušší to je. Nepředával jsem parametr url, takže ono zmíněné řešení mě pokoplo správným směrem – CakePHP dokáže využívat parametry u metody get!!! Takže jsem do controlleru přidal jednoduchou bezparametrickou metodu add(), ve které tyto parametry přečtu:

function add(){
        if(isset($_GET['vstup']))
            $vstup = $_GET['vstup'];
   . . .

A teď můžu tento controller bez problému volat i s adresou jako s parametrem (např. http://www.libisemi.cz/add?vstup=http%3A%2F%2Fshmoulicek.unas.cz/ ) . Aneb potvrzuji moje oblíbené rčení i chování: proč dělat věci jednoduše, když jdou dělat i složitě :-).


Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *