I have a bookmarklet that injects Javascript into a page and opens up an iframe with an HTML page I have created that allows a user to subscribe to a page directly from my bookmarklet.

Issue is, certain domains (Twitter and Facebook being two) do not allow me to inject Javascript, so I have to pop up a window instead.

Javascript console when on Facebook:

Refused to load the script script name because it violates the following Content Security Policy directive: "script-src https://.facebook.com http://.facebook.com https://.fbcdn.net http://.fbcdn.net *.facebook.net *.google-analytics.com *.virtualearth.net .google.com 127.0.0.1: *.spotilocal.com:* chrome-extension://lifbcibllhkdhoafpjfnlhfpfgnpldfl 'unsafe-inline' 'unsafe-eval' https://.akamaihd.net http://.akamaihd.net *.atlassolutions.com".

Right now in my bookmarklet I am just checking to see if the URL matches those domains before I try to inject JS, and if it does, I pop open a new window. For obvious reasons, this is not a good practice.

What is a good method of checking if a Javascript function was allowed to run on the current page or not, and if not, to open a new window?

有帮助吗?

解决方案

There is no way to know with absolute certainty that an external script failed to load. Even when there is no security policy, an external script could fail to load because of other problems. The only One thing you can really do is set a timeout and if the script hasn't completed some action before the timeout expires, assume it has failed to load.

EDIT: I stand corrected by Sean below. His suggestion also worked in Chrome and Firefox on Windows. The solution is something like this:

newScript.addEventListener('error', function(){ console.log('script failed to load') });

For the specific question of how to check if the page header returns a Content Security Policy which will block your external script, the only solution I know of is to check the HTTP header using AJAX.

Here is some example code. I've tested this on Facebook.

req = new XMLHttpRequest;
req.onreadystatechange = function(){if (req.readyState==4) console.log(req.getResponseHeader('content-security-policy'))};
req.open("HEAD", document.location.href);
req.send();

其他提示

Bookmarklets should be allowed to run whatever the security policy is. If not, it is a browser bug - at least if I understand this correctly. But the bookmarklet may be forbidden to do some things. If you use try-catch you can find out if an action was allowed or not.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top