问题
I am making a Firefox add-on. It needs to
1) Read the webpage
2) Based on that, send information in a POST to my site,
3) Display a text based on what my site returns.
I cannot get this to work on Facebook.com and I believe that it is due to Facebook's restrictive Content-security-policy. I cannot get the add-on content_script to send a POST.
I have tried:
var url = 'https://mysite.com';
var request = new XMLHttpRequest();
request.open("POST", url, true);
request.onload = function () {
alert("returned");
};
request.send();
On non-Facebook sites this works. On Facebook, there is no activity in the Network tab. The console gives me an error:
Content Security Policy: The page's settings blocked the loading of a resource at ...
I have also tried doing something with an iframe:
var onload = "var url = 'https://mysite.com';
var request = new XMLHttpRequest();
request.open('GET', url, true);
request.send();
request.onload = function(){alert();};";
var iframe_wrapper = window.document.createElement("div");
iframe_wrapper.innerHTML='<iframe onLoad="'+onload+'"; src="https://mysite.com"></iframe>';
window.document.body.appendChild(iframe_wrapper);
On non-Facebook sites, two calls are made: the inital iframe src call and then the call in the onLoad function.
On Facebook, only the iframe call is made, which is successful. The console then gives an error (first time I try):
ReferenceError: reference to undefined property la.stack
ReferenceError: reference to undefined property n.name
Is there a way around this? Note that this does work with my Chrome extension (I use the first straight-forward method).
回答1:
Yes set the csp rules. I got this from another topic here: How to add Content Security Policy to Firefox extension
But this version is slightly different.
But copy paste this:
var httpRequestObserver =
{
observe: function(subject, topic, data)
{
Cu.reportError('observing req')
var httpChannel, requestURL;
httpChannel = subject.QueryInterface(Ci.nsIHttpChannel);
requestURL = httpChannel.URI.spec;
if (httpChannel.responseStatus !== 200) {
return;
}
var cspRules;
var mycsp;
// thre is no clean way to check the presence of csp header. an exception
// will be thrown if it is not there.
// https://developer.mozilla.org/en-US/docs/XPCOM_Interface_Reference/nsIHttpChannel
console.info('reading response headers on requestURL = ', requestURL)
try {
console.warn('trying to set init')
cspRules = httpChannel.getResponseHeader("Content-Security-Policy");
mycsp = _getCspAppendingMyHostDirective(cspRules);
httpChannel.setResponseHeader('Content-Security-Policy', mycsp, false);
console.warn('set init done')
} catch (e) {
try {
console.warn('trying to set fallback')
// Fallback mechanism support
cspRules = httpChannel.getResponseHeader("X-Content-Security-Policy");
mycsp = _getCspAppendingMyHostDirective(cspRules);
httpChannel.setResponseHeader('X-Content-Security-Policy', mycsp, false);
console.warn('fallback set done')
} catch (e) {
// no csp headers defined
console.warn('no csp headers defined so SHOULD be able to inject script here url = ' + requestURL);
return;
}
}
}
};
Cu.import('resource://gre/modules/devtools/Console.jsm');
/**
* @var cspRules : content security policy
* For my requirement i have to append rule just to 'script-src' directive. But you can
* modify this function to your need.
*
*/
function _getCspAppendingMyHostDirective(cspRules) {
var rules = cspRules.split(';');
var scriptSrcFound = false;
for (var ii = 0; ii < rules.length; ii++) {
if ( rules[ii].toLowerCase().indexOf('script-src') != -1 ) {
rules[ii] = 'script-src * \'unsafe-inline\' \'unsafe-eval\''; // define your own rule here
scriptSrcFound = true;
}
}
return rules.join(';');
}
Then on startup of addon run this code:
Services.obs.addObserver(httpRequestObserver, 'http-on-examine-response', false);
and on shutdown of addon run this code:
Services.obs.removeObserver(httpRequestObserver, 'http-on-examine-response', false);
来源:https://stackoverflow.com/questions/23501645/content-security-policy-and-facebook-add-on-not-working