服务器端检测iframe

服务器端检测iframe,iframe,server,http-referer,Iframe,Server,Http Referer,相关问题: 我觉得奇怪的是,我们显然无法从服务器端知道页面是否通过iframe加载。大多数答案都说它只能从浏览器中检测到,我只是不明白为什么 在浏览器中,我们可以访问document.referer,它清楚地指示我们来自的url。在服务器端使用req.headers.referer也有类似的功能 我刚刚用一个本地iframe对其进行了测试,结果如下: referer http://localhost:8888/tests/chatbotIframeIntegration // The page

相关问题:

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

在浏览器中,我们可以访问
document.referer
,它清楚地指示我们来自的url。在服务器端使用
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。所以,如果我知道我的应用程序应该运行到哪个url,我肯定可以有一些逻辑来判断我是否从外部网站调用我的服务器,不是吗

另外,浏览器使用
referer
而服务器使用
referer
(一个r)…,这也很奇怪

我通过实验获得了更多的经验,以下是我到目前为止学到的


正如我所想,我们可以通过
document.referer
(浏览器)和
req.headers.referer
(服务器)来解析referer

因此,可以检测当前引用者是否与我们的宿主服务器不同,在这种情况下,我们知道查询来自iframe

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

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

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


现在,我的实际需求有点不同。我需要知道我的
/page2
是否是从我自己的另一个域(跨域)加载的,这很容易知道,因为在服务器端和浏览器端,引用者与我自己的域不同

我的集成测试变得有点复杂,因为我有一个
/tests/iframeigration
页面,其中包含一个iframe,它从同一个域加载另一个页面
/page2
。(相对url)

重点是测试iframe集成是否按预期工作,因为它运行在同一个域上,所以我无法确定是否通过iframe加载它

对于这种特殊情况,我在url中添加了一个
/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;
  }
};