<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Code-It &#187; userscript</title>
	<atom:link href="http://lois.di-qual.net/blog/tag/userscript/feed/" rel="self" type="application/rss+xml" />
	<link>http://lois.di-qual.net/blog</link>
	<description></description>
	<lastBuildDate>Tue, 30 Oct 2012 19:19:29 +0000</lastBuildDate>
	<language>fr-FR</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>Bloquer ou monitorer AJAX à partir d&#8217;un script GreaseMonkey (ou Userscript)</title>
		<link>http://lois.di-qual.net/blog/bloquer-ou-monitorer-ajax-a-partir-dun-script-greasemonkey-ou-userscript/</link>
		<comments>http://lois.di-qual.net/blog/bloquer-ou-monitorer-ajax-a-partir-dun-script-greasemonkey-ou-userscript/#comments</comments>
		<pubDate>Fri, 01 Jun 2012 00:13:05 +0000</pubDate>
		<dc:creator>Loïs Di Qual</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[greasemonkey]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[userscript]]></category>

		<guid isPermaLink="false">http://lois.di-qual.net/blog/?p=60</guid>
		<description><![CDATA[Facebook a récemment ajouté une fonctionnalité qui m&#8217;est très désagréable: la notification de la lecture des messages à l&#8217;expéditeur. Impossible dès lors d&#8217;ignorer un message instantané sans que la personne le sache, or c&#8217;est un droit immuable qui devrait être inscrit au burin dans la roche des droits de l&#8217;homme. Modification de XMLHttpRequest Pour empêcher [...]]]></description>
				<content:encoded><![CDATA[<p>Facebook a récemment ajouté une fonctionnalité qui m&#8217;est très désagréable: la notification de la lecture des messages à l&#8217;expéditeur. Impossible dès lors d&#8217;ignorer un message instantané sans que la personne le sache, or c&#8217;est un droit immuable qui devrait être inscrit au burin dans la roche des droits de l&#8217;homme.</p>
<h2>Modification de XMLHttpRequest</h2>
<p>Pour empêcher ces notifications, il faut empêcher l&#8217;envoi de données vers <code class="codecolorer text default"><span class="text">http(s)://www.facebook.com/ajax/mercury/change_read_status.php</span></code> à partir d&#8217;un script Greasemonkey. Le principe du blocage consiste en la modification de l&#8217;objet <code class="codecolorer text default"><span class="text">XMLHttpRequest</span></code> pour que la méthode <code class="codecolorer text default"><span class="text">open</span></code> n&#8217;autorise pas l&#8217;ouverture du socket vers la page en question:</p>
<div class="codecolorer-container javascript twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #006600; font-style: italic;">// On sauvegarde la méthode open originale</span><br />
window.<span style="color: #660066;">XMLHttpRequest</span>.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">trueOpen</span> <span style="color: #339933;">=</span> window.<span style="color: #660066;">XMLHttpRequest</span>.<span style="color: #660066;">prototype</span>.<span style="color: #000066;">open</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #006600; font-style: italic;">// On modifie la méthode open avec la notre</span><br />
window.<span style="color: #660066;">XMLHttpRequest</span>.<span style="color: #660066;">prototype</span>.<span style="color: #000066;">open</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <br />
&nbsp; <span style="color: #006600; font-style: italic;">// Du code pour bloquer ou logger ce qui se passe</span><br />
&nbsp; <span style="color: #006600; font-style: italic;">// On peut notamment regarder ce qu'il y a dans arguments</span><br />
&nbsp; <span style="color: #006600; font-style: italic;">// pour bloquer: return;</span><br />
<br />
&nbsp; <span style="color: #006600; font-style: italic;">// Si on ne souhaite pas bloquer l'ouverture du socket,</span><br />
&nbsp; <span style="color: #006600; font-style: italic;">// on fait appel à la méthode originale</span><br />
&nbsp; <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">trueOpen</span>.<span style="color: #660066;">apply</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">,</span> arguments<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>Vous pouvez ainsi intercepter chaque appel aux méthodes de <code class="codecolorer text default"><span class="text">XMLHttpRequest</span></code>, et les bloquer ou les rerouter à votre guise. Pour la liste complète des méthodes en question, je vous invite à consulter <a href="http://www.w3.org/TR/XMLHttpRequest">sa documentation W3C</a>.</p>
<p>Dans le cas d&#8217;un blocage (pas d&#8217;appel à <code class="codecolorer text default"><span class="text">trueOpen</span></code>), voici ce qu&#8217;il va se passer du côté de la page monitorée:</p>
<div class="codecolorer-container javascript twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #006600; font-style: italic;">// Instanciation normale de notre objet</span><br />
<span style="color: #003366; font-weight: bold;">var</span> xhr <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> XMLHttpRequest<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #006600; font-style: italic;">// Rien ne se passe, l'instance de xhr n'est pas modifiée et le socket n'est pas ouvert</span><br />
xhr.<span style="color: #000066;">open</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;get&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;page_bloquee.html?param=1&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #006600; font-style: italic;">// Le send échoue car le socket n'est pas ouvert</span><br />
xhr.<span style="color: #660066;">send</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span></div></td></tr></tbody></table></div>
<p>L&#8217;appel à <code class="codecolorer text default"><span class="text">xhr.send</span></code> ne provoque aucune erreur, du moins sous Chrome.</p>
<h2>Le script Greasemonkey</h2>
<p>Le script abordé précédemment suppose que vous soyez dans le scope de la page dont vous souhaitez monitorer les appels AJAX. Ce n&#8217;est pas le cas pour les scripts GreaseMonkey. Comme expliqué très judicieusement <a href="http://stackoverflow.com/a/10828021/646960">dans ce post sur StackOverflow</a>, Firefox et Chrome exécutent ces scripts dans une sandbox qui ne permet pas d&#8217;accéder à l&#8217;environnement javascript de la page concernée.</p>
<p>Néanmoins, il existe une méthode assez simple pour sortir de cette sandbox: injecter un élément <code class="codecolorer text default"><span class="text">script</span></code> dans la page en question qui exécutera le code de notre choix.</p>
<div class="codecolorer-container javascript twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #003366; font-weight: bold;">function</span> main<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; <span style="color: #006600; font-style: italic;">// Notre code précédent</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #006600; font-style: italic;">// On crée un élément &lt;script&gt;&lt;/script&gt; et on l'injecte dans la page à contrôler</span><br />
<span style="color: #006600; font-style: italic;">// Dans cet élément, on copie la fonction main afin qu'elle soit exécutée</span><br />
<span style="color: #003366; font-weight: bold;">var</span> script <span style="color: #339933;">=</span> document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;script&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
script.<span style="color: #660066;">textContent</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;(&quot;</span> <span style="color: #339933;">+</span> main.<span style="color: #660066;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;)();&quot;</span><span style="color: #339933;">;</span><br />
document.<span style="color: #660066;">body</span>.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>script<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<h2>Le code final</h2>
<div class="codecolorer-container javascript twitlight" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #003366; font-weight: bold;">function</span> main<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; window.<span style="color: #660066;">XMLHttpRequest</span>.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">trueOpen</span> <span style="color: #339933;">=</span> window.<span style="color: #660066;">XMLHttpRequest</span>.<span style="color: #660066;">prototype</span>.<span style="color: #000066;">open</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; window.<span style="color: #660066;">XMLHttpRequest</span>.<span style="color: #660066;">prototype</span>.<span style="color: #000066;">open</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// ...</span><br />
&nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// this.trueOpen.apply(this, arguments);</span><br />
&nbsp; <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #003366; font-weight: bold;">var</span> script <span style="color: #339933;">=</span> document.<span style="color: #660066;">createElement</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;script&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
script.<span style="color: #660066;">textContent</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;(&quot;</span> <span style="color: #339933;">+</span> main.<span style="color: #660066;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;)();&quot;</span><span style="color: #339933;">;</span><br />
document.<span style="color: #660066;">body</span>.<span style="color: #660066;">appendChild</span><span style="color: #009900;">&#40;</span>script<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>En ce qui concerne le blocage de la notification facebook, voici <a href="https://github.com/ldiqual/facebook-read-status-disabler">facebook-read-status-disabler</a>. Il est également à noter que ce monitoring ne fonctionnera pas avec Internet Explorer car celui-ci utilise un autre objet pour les requêtes AJAX. Un script plus complet est disponible sur github: <a href="https://github.com/creotiv/AJAX-calls-intercepter">AJAX Calls Intercepter</a>, avec notamment la prise en compte d&#8217;Internet Explorer.</p>
]]></content:encoded>
			<wfw:commentRss>http://lois.di-qual.net/blog/bloquer-ou-monitorer-ajax-a-partir-dun-script-greasemonkey-ou-userscript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
