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ě :-).