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