Обнаружение серверной части iframe - PullRequest
0 голосов
/ 31 января 2020

Связанные проблемы: Обнаружение на стороне сервера того, что страница отображается внутри IFrame

Я нахожу странным, что мы не можем, очевидно, узнать со стороны сервера, загружена ли страница. через фрейм. Большинство ответов говорят, что это можно обнаружить только из браузера, я просто не понимаю, почему.

В браузере у нас есть доступ к document.referrer, который ясно указывает на 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 запрос приходит от Итак, если я знаю, по какой ссылке должно работать мое приложение, у меня определенно может быть лог c, который определяет, звоню ли я своему серверу с внешнего сайта, не так ли?

Также Довольно странно, что браузер использует referrer, а сервер использует referer (one r) ...

1 Ответ

0 голосов
/ 26 февраля 2020

Я приобрел больше опыта в результате экспериментов, поэтому вот что я узнал до сих пор.


Как я и думал, мы можем разрешить реферера через document.referrer (браузер) и req.headers.referer (сервер).

Таким образом, можно определить, отличается ли текущий реферер от нашего хост-сервера, и в этом случае мы знаем, что запрос поступил из iframe.

С серверной стороны становится сложнее узнать, была ли страница вашего сайта загружена через iframe на этом же сайте. В таком случае невозможно автоматически определить, запускаем ли мы страницу из iframe или нет.

Например, если у вас есть iframe на странице /index, который загружает /page2 page, то вы не можете узнать, со стороны сервера, был ли / page2 загружен из iframe (on / index) или из перехода на /page2.

И именно поэтому люди говорят, что есть со стороны сервера невозможно узнать, была ли страница загружена через iframe. Потому что это неясно.


Теперь моя реальная потребность была немного другой. Мне нужно было знать, был ли мой /page2 загружен из другого домена, который принадлежит мне (кросс-домен), и это довольно просто узнать, поскольку реферер будет отличаться от моего собственного домена, как на стороне сервера, так и на стороне браузера.

С моими интеграционными тестами стало немного сложнее, потому что у меня была страница /tests/iframeIntegration, которая содержит iframe, который загружает другую страницу /page2 из того же домена. (относительный URL)

Цель состояла в том, чтобы проверить, работала ли интеграция iframe должным образом, и поскольку она работала в том же домене, я не мог определить, загружал ли я ее через iframe.

Для этого конкретного случая я добавил /page2?iframe=true в URL. Это самый простой обходной путь, который я нашел, который работает универсально (браузер + сервер).

Вот несколько служебных скриптов:

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;
  }
};

...