iframe обнаружения на стороне сервера

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

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

Кроме того, довольно странно, что браузер использует referrer, а сервер использует referer (один r)...


person Vadorequest    schedule 31.01.2020    source источник


Ответы (1)


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


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

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

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

Например, если у вас есть iframe на странице /index, который загружает /page2 страницу, то вы не можете знать со стороны сервера, была ли загружена /page2 из iframe (в /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;
  }
};

person Vadorequest    schedule 26.02.2020