2

En bref, au lieu d'alerter les URL et le corps de la réponse, je voudrais l'envoyer à mon application. Ce code fonctionne mais je ne peux pas utiliser GM_xmlhttpRequest à moins que je ne l'accorde.Pourquoi la modification de la subvention de none à GM_xmlhttpRequest casse-t-elle mon code?

Ne changez rien d'autre que le code casse par magie. Je ne suis pas sûr de ce qui est changé et comment le réparer. Je pensais pouvoir utiliser console.log et copier/coller les données dans mon application, mais Facebook désactive console.log. J'ai pensé à faire xmlhttpRequest mais cela aussi est en quelque sorte bloqué. J'ai testé en exécutant du code dans une console. Les 3 lignes semblent fonctionner partout sauf sur un domaine Facebook. Je crois que cela a quelque chose à voir avec CORS.

// ==UserScript== 
// @name  FBTest 
// @namespace test 
// @include  https://*.facebook.com/* 
// @version  1 
// @grant  none 
// ==/UserScript== 
//change none to GM_xmlhttpRequest 
(function() { 
    var proxied = window.XMLHttpRequest.prototype.open; 
    window.XMLHttpRequest.prototype.open = function(method, url) { 
     alert(url); 
     return proxied.apply(this, [].slice.call(arguments)); 
    }; 
})(); 
+0

Utilisez [ 'GM_xmlhttpRequest'] (https://wiki.greasespot.net/GM_xmlhttpRequest) au lieu de' window.XMLHttpRequest' – Mottie

+1

@Mottie - le code essaye d '"intercepter" la fonction ouverte de XMLHttpRequest, n'utilise pas réellement XMLHttpRequest –

+0

le problème provient du fait que tout script avec @grant * autre chose que none * s'exécute dans un environnement plus sécurisé portée. Je pensais à l'origine que vous pouviez utiliser unsafeWindow au lieu de window - cependant cela ne fonctionne pas non plus, car '.open' est alors rendu inutilisable à cause de la portée privilégiée dans laquelle s'exécute votre code' open'. –

Répondre

4

Lorsque vous accordez GM_xmlhttpRequest, it switches on the sandbox - ce qui signifie que vous ne pouvez pas accéder à window.XMLHttpRequest comme ça que dans un contexte différent. Pour contourner ce problème, utilisez script injection pour intercepter l'AJAX. Et, utilisez messaging ou un événement personnalisé pour accéder aux données dans le contexte de votre script.

Voici un exemple de script en utilisant un événement personnalisé (moins vulnérable aux exploits 3 parties):

// ==UserScript== 
// @name  _Intercept AJAX with grant/sandbox on 
// @match  https://*.facebook.com/* 
// @grant  GM_xmlhttpRequest 
// ==/UserScript== 

function xmlOpenIntercept() { 
    var proxied = window.XMLHttpRequest.prototype.open; 
    window.XMLHttpRequest.prototype.open = function (method, newUrl) { 
     var cEvnt = new CustomEvent ('newAjaxStart', {'detail': newUrl}); 
     document.body.dispatchEvent (cEvnt); 

     return proxied.apply (this, [].slice.call (arguments)); 
    }; 
} 
addJS_Node (null, null, xmlOpenIntercept); //-- Injects code 


//--- This code listens for the right kind of message. 
document.body.addEventListener ("newAjaxStart", receiveAjaxMessage); 

function receiveAjaxMessage (zEvent) { 
    console.log ("Intercepted AJAX to: ", zEvent.detail); 
} 

function addJS_Node (text, s_URL, funcToRun, runOnLoad) { 
    var D         = document; 
    var scriptNode       = D.createElement ('script'); 
    if (runOnLoad) scriptNode.addEventListener ("load", runOnLoad); 
    scriptNode.type       = "text/javascript"; 
    if (text)  scriptNode.textContent = text; 
    if (s_URL)  scriptNode.src   = s_URL; 
    if (funcToRun) scriptNode.textContent = '(' + funcToRun.toString() + ')()'; 

    var targ = D.getElementsByTagName ('head')[0] || D.body || D.documentElement; 
    targ.appendChild (scriptNode); 
} 
+0

FYI, document.head a été dans firefox depuis 4.0 - pas besoin de 'getElementsByTagName' plus –

+0

@JaromandaX, sauf s'il n'y a pas exactement 1' 'présent lorsque le script fonctionne. –

+0

Je n'ai jamais considéré ça! - bonne réponse en passant, m'a aussi aidé: p –