温馨提示:本文翻译自stackoverflow.com,查看原文请点击:其他 - Server side detection iframe
iframe server http-referer

其他 - 服务器端检测iframe

发布于 2020-04-10 10:13:47

相关问题: 服务器端检测页面是否显示在IFrame中

我觉得很奇怪,我们显然无法从服务器端知道页面是否通过iframe加载。大多数答案都说只能从浏览器中检测到,我只是不知道为什么。

在浏览器中,我们可以访问document.referrer它,以清楚地表明我们来自的网址。在服务器端,有类似的东西req.headers.referer

我刚刚在本地iframe中对其进行了测试,结果如下:

referer http://localhost:8888/tests/chatbotIframeIntegration // The page containing the iframe
referer http://localhost:8888/chatbot // The page displayed within an iframe
referer undefined // seems to be undefined sometimes, maybe due to HMR?)

我绝对可以检测到请求的网址。因此,如果我知道我的应用程序应该在哪个url中运行,我绝对可以使用某种逻辑来弄清楚是否要从外部网站调用服务器,不是吗?

另外,浏览器使用referrer和服务器使用referer(一个)也很奇怪

查看更多

提问者
Vadorequest
被浏览
41
Vadorequest 2020-02-26 21:34

通过实验,我获得了更多经验,因此,这是到目前为止我学到的东西。


如我所料,我们可以通过document.referrer(浏览器)和req.headers.referer(服务器)解析引荐来源网址

因此,可以检测当前引荐来源网址是否不同于我们的托管服务器,在这种情况下,我们知道查询来自iframe。

当您想从服务器端知道站点中的页面是否已通过同一站点中的iframe加载时,这将变得更加棘手。在这种情况下,无法自动检测是否正在从iframe运行页面。

例如,如果页面上有一个iframe /index可以加载/page2页面,那么就无法从服务器端知道/ page2是从iframe(在/ index上)加载还是从导航到/ page2。

这就是为什么人们说无法从服务器端知道是否通过iframe加载了页面。因为不确定。


现在,我的实际需求有所不同。我需要知道我/page2是否从我自己的另一个域(跨域)加载了,这很容易知道,因为在服务器端和浏览器端,引荐来源网址都不同于我自己的域。

集成测试使它变得更加复杂,因为我有一个/tests/iframeIntegration页面,其中包含一个iframe,该iframe会加载/page2同一域中的另一个页面(相对网址)

关键是要测试iframe集成是否按预期工作,并且因为它在同一域上运行,所以我无法确定是否通过iframe进行加载。

对于这种特殊情况,我/page2?iframe=true在网址中添加了一个这是我发现的最简单的解决方法,可以普遍使用(浏览器+服务器)。

以下是一些实用程序脚本:

import { isBrowser } from '@unly/utils';
import includes from 'lodash.includes';

/**
 * Resolves whether the current web page is running as an iframe from another page
 *
 * Iframes are only detectable on the client-side
 * Also, using iframe=true as search parameter forces iframe mode, it's handy when using an iframe from the same domain
 * (because same-domain iframes aren't detected when comparing window.parent and window.top since it's the same window)
 *
 * @return {boolean}
 * @see https://stackoverflow.com/a/326076/2391795
 */
export const isRunningInIframe = (): boolean => {
  if (isBrowser()) {
    try {
      return window.self !== window.top || includes(document.location.search, 'iframe=true');
    } catch (e) {
      return null; // Can't tell
    }
  } else {
    return null; // Can't tell
  }
};

/**
 * Resolve the iframe's referrer (the url of the website the iframe was created)
 *
 * Helpful to know which of our customer use our app through an iframe, and analyse usage
 * May not always work due to security concerns
 *
 * @return {string}
 * @see https://stackoverflow.com/a/19438406/2391795
 */
export const getIframeReferrer = (): string => {
  if (isRunningInIframe()) {
    try {
      return document.referrer || null;
    } catch (e) {
      return null;
    }
  } else {
    return null;
  }
};