6

I have the following code to check whether the webpage can be framed or not at all:

var req = new XMLHttpRequest();
var test = req.open('GET', link, false);
console.log("test",test); //ALWAYS undefined
if(req.send(null)){ //ALWAYS throws error NS_ERROR_FAILURE
    var headers = req.getAllResponseHeaders().toLowerCase();
    console.log("headers");
}else{
    console.log("FAILED");
}

I tested it with several links, frameable or not, but always fails. Do you know exactly why?

Links:

Ninjakannon
  • 3,751
  • 7
  • 53
  • 76
Fane
  • 1,978
  • 8
  • 30
  • 58

1 Answers1

5
  • test is undefined because open() is declared void, it does not return any value. Check out MDN on the open method.
  • Why are you passing null to send? (see edit) If you intend to call the overload of send that doesn't take any argument you should just call req.send(); instead if you want to call another version of the method you should pass a Blob, Document, DOMString or FormData, but null won't work.
    EDIT: Often the method is invoked as send(null); it seems to be because at some point in history (is that old?) the argument of send was mandatory. This question unravels the mystery.

  • Moreover, again send doesn't return any value so the condition in the if will never evaluate true. MDN documents also the send method.

  • Last, you are performing a cross-domain request, i.e. you're asking for content that is located on another domain. XMLHttpRequest doesn't handle that, most likely you will end up with this error:

    XMLHttpRequest cannot load link. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin origin is therefore not allowed access.

    Check out this question and this on StackOverflow if you need more information about that.

You may want to take a look at Using XMLHttpRequest again on the MDN network, it has many reliable examples that can help you get acquainted with these requests.


EDIT: expanding on the topic iframe embeddability.

Detecting reliably if a website can be embedded in an iframe is difficult, as this question shows. Detecting (or preventing) frame buster in JavaScript is like a dog chasing its own tail.

Nevertheless, a website that doesn't want to be incorporated, hopefully would send the X-Frame-Options: DENY header in its response. This is not very useful, because you can't perform cross domain requests: your request would fail before getting to know if the X-Frame-Options header is even set. For completeness, this is the way of checking if the response to an XMLHttpRequest contains a given header (but note that this would work only within the same domain, which is presumably under your control, and you would know already if a page is 'frameable'):

function checkXFrame() {
    var xframe = this.getResponseHeader("X-Frame-Options");
    if (!xframe) {
        alert("Frameable.");
        return;
    }
    xframe = xframe.toLowerCase();
    if (xframe == "deny") {
        alert("Not frameable.");
    } else if (xframe == "sameorigin") {
        alert("Frameable within the same domain.");
    } else if (xframe.startsWith("allow-from")) {
        alert("Frameable from certain domains.");
    } else {
        alert("Someone sent a weird header.");
    }
}

var oReq = new XMLHttpRequest();
oReq.open("HEAD" /* use HEAD if you only need the headers! */, "yourpage.html");
oReq.onload = checkXFrame;
oReq.send();

(this code doesn't check for 404 or any other error!)

Community
  • 1
  • 1
Pietro Saccardi
  • 2,602
  • 34
  • 41
  • 1
    on the "why pass null to send?" question, see http://stackoverflow.com/questions/15123839/why-do-we-pass-null-to-xmlhttprequest-send - it's incorrect to say `null` won't work – CupawnTae Sep 18 '15 at 14:11
  • @CupawnTae oh! interesting, I didn't know that. I'll update the answer. – Pietro Saccardi Sep 18 '15 at 14:16
  • 1
    it was a minor point anyway, you already got my upvote :-) Also might be worth wondering what all this has to do with whether content can be displayed in an iframe... – CupawnTae Sep 18 '15 at 14:18
  • I don't understand... so how exactly should I perform a request to a website and check if it could be contained in an iframe? As for example, could I check if www.facebook.com could go into an iframe? – Fane Sep 22 '15 at 20:05
  • @Fane Any website can go into an `iframe`, the problem is that many websites have a frame buster. Check http://stackoverflow.com/questions/7422300/checking-if-a-website-doesnt-permit-iframe-embed -- it's a rather complicated topic because detecting a frame buster is the equivalent as bypassing it in my opinion. – Pietro Saccardi Sep 22 '15 at 20:11
  • @PietroSaccardi Yes... I know... but please, so I can give you the rep and actually figure this out could you please explain me how to do this in javascript? `$url = "http://stackoverflow.com"; $header = get_headers($url, 1); echo $header["X-Frame-Options"];` – Fane Sep 22 '15 at 20:44
  • @Fane that is PHP code, is a different thing. I included the answer to your question in... the answer to your question. – Pietro Saccardi Sep 22 '15 at 21:14
  • So I can't check if www.facebook.com is frameable with this code? Is cross-domain javascript that limited? I would have thought that if the browser recognizes a certain website can't be shown then this prohibition could also be detected... – Fane Sep 22 '15 at 21:27
  • XMLHttpRequest servers mainly the purpose of dynamically loading content into your page or interacting with REST API, it doesn't give you raw access to a socket, so yes, is somewhat 'limited'. That code can't allow you to check if you can embed FB in a frame. The reason why the prohibition can't be detected is because here there are many things happening on different levels. If you read through the linked material the motivation for the design choices should become more clear. – Pietro Saccardi Sep 22 '15 at 21:39
  • @Fane I presume that I answered you question? – Pietro Saccardi Sep 26 '15 at 13:33