window.name как транспорт данных: правильный подход?

Обзор и исходный вопрос

window.name — интересный зверь. Описание MDN намекает на первоначальное намерение:

Имя окна используется в основном для установки целей для гиперссылок и форм. Windows не обязательно должны иметь имена.

Итак, это означает, что мы можем открыть консоль в этом окне и написать:

var win = window.open('http://google.com', 'el goog');

...а затем пропустите его через блокировщик всплывающих окон, который должен открыть google.com в окне с именем el goog. Я не могу получить доступ к свойству name элемента win из-за той же политики происхождения, но если я открою консоль в новом окне и наберу name, я получу "el goog".

Если я отправлю окно обратно в домен, из которого я его открыл (в данном случае stackoverflow.com), я могу получить свойство name, и оно не изменилось.

win.location.replace(location.href);
win.name; // "el goog"

Это означает, что мы можем иметь своего рода междоменное хранилище сеансов, установив свойство name окна.

Если бы google.com изменил значение window.name до того, как окно было отправлено обратно в исходный домен, вместо el goog мы увидели бы новое значение. Это можно использовать в качестве междоменного транспорта данных, аналогичного JSONP или CORS.

Я немного поискал, чтобы найти больше информации, и, по-видимому, dojo считает, что это законно как транспорт. Впрочем, меня это как-то совсем не успокаивает. Итак, мой вопрос: используют ли какие-либо авторитетные сайты window.name в качестве транспорта данных? Я думаю, это будет легко заметить, потому что в их документах будет сказано что-то вроде добавить «обратный вызов» в строку запроса для JSONP или добавить «независимо» для window.name, но я никогда этого не делал. видел что-то подобное. Кто-нибудь действительно замечал это в дикой природе?


Альтернативный вопрос

Может случиться так, что никто на самом деле не использует эту технику; если это правда, то (как указал Роб В.) на поставленный выше вопрос нет ответа. Итак, мой альтернативный вопрос: какие проблемы с этим подходом? Это может помочь объяснить, почему он на самом деле не был принят.

На мой взгляд, у этого подхода есть как минимум два преимущества перед JSONP.

  • С JSONP вы доверяете скрипту иностранного происхождения для запуска на вашем домене. С window.name любые сценарии, включенные вредоносным сайтом, будут выполняться в их собственном домене.

  • С JSONP нет возможности передавать большие данные (что-то слишком большое для URL-адреса) и нет возможности сделать HTTP POST. С помощью window.name мы можем публиковать произвольные данные любого размера.

Каковы недостатки?


Пример реализации

Вот очень простой пример реализации клиента. Это не обрабатывает запросы POST, только GET.

function fetchData(url, callback) {
    var frame = document.createElement('iframe');
    frame.onload = function() {
        frame.onload = function() {
            callback(frame.contentWindow.name);
            frame.parentNode.removeChild(frame);
        }
        frame.src = 'about:blank';
    }
    frame.src = url;
    document.body.appendChild(frame);
}

// using it

fetchData('http://somehost.com/api?foo=bar', function(response) {

    console.log(response);

});​

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

Вот немного более длинный пример, который может выполнять запросы POST: http://jsfiddle.net/n9Wnx/2/< /а>


Сводка

Насколько я могу судить, window.name не прижился как транспорт данных. Интересно, правильно ли мое восприятие (отсюда исходный вопрос), и если да, то мне интересно, почему это так. Я перечислил несколько преимуществ window.name по сравнению с JSONP. Может ли кто-нибудь определить некоторые недостатки, которые могли помешать внедрению этого метода?

Более того, может ли кто-нибудь дать мне вескую причину, почему я не должен использовать winow.name в качестве транспорта данных?


person Dagg Nabbit    schedule 12.05.2012    source источник
comment
@RobW что-то вроде «да», API blahboop.com будет отвечать на запросы либо с помощью JSONP, либо с помощью window.name ... где blahboop.com - это то, что люди действительно используют. Что-то, чтобы добавить легитимности этой идее. Я почти уверен, что справлюсь с реализацией, но я думаю, что наличие законного сайта, использующего эту технику, может говорить о надежности (по крайней мере, вероятность того, что поведение будет удалено в будущем, меньше)   -  person Dagg Nabbit    schedule 13.05.2012
comment
Знание того, что определенный сайт использует метод, не делает метод более мощным/действительным. Предположим, что ответом было то, что Google использует эту технику. Что дает? Вопрос был бы более отвечающим, если бы он был сформулирован так: «Есть ли подводные камни/возможные проблемы?»   -  person Rob W    schedule 13.05.2012
comment
@RobW Я думал об этом, но мне казалось, что я в основном говорил, почему никто не использует эту технику, и я не был уверен, что на самом деле это правда, что никто ее не использует, поэтому я решил спросить об этом. первый.   -  person Dagg Nabbit    schedule 13.05.2012
comment
Кстати, в каких браузерах вы тестировали эту функцию? Если вы хотите, я могу протестировать эту функцию примерно в 26 браузерах (я настроил виртуальную машину, содержащую их, см. мой последний вопрос, если вы хотите сделать то же самое). Когда каждый браузер поддерживает эту функцию, она может быть полезной. Возможный недостаток заключается в том, что для каждого переноса необходимо отображать весь документ, что делает его использование более дорогим, чем JSONP.   -  person Rob W    schedule 14.05.2012
comment
@RobW, это было бы здорово, вы можете использовать последнюю ссылку jsfiddle ... Однако я не знаю, как вы будете тестировать публикацию формы без какого-либо скрипта на стороне сервера. Я могу собрать что-нибудь для этого, если хотите, просто дайте мне знать, на каком языке.   -  person Dagg Nabbit    schedule 14.05.2012
comment
@RobW вроде OT (я не хотел испортить вашу другую тему), но я думаю, что ваша установка была бы действительно идеальной, если бы вы могли протестировать ее на OSX и Linux ... старые версии Safari на Mac печально известны для странного поведения, а в Linux у вас есть konqy и странные выбросы, такие как прозрение. Было бы неплохо подключить его и к эмулятору Android. Мне интересно, все ли эти браузеры обрабатывают window.name одинаково, я думаю, что на самом деле это совершенно не указано... во всяком случае, не в ES, и почти уверен, что это не часть DOM. Может быть, это настоящая причина, по которой он не используется?   -  person Dagg Nabbit    schedule 14.05.2012
comment
Для всех домашних страниц моей виртуальной машины установлено значение http://10.0.2.2:8888/, на котором я запускаю сервер Node.js. Все, что мне нужно, это файлы для настройки. Что касается виртуальных машин: целью была одна виртуальная машина, содержащая все браузеры. У меня также есть виртуальная машина OSX, и моя основная среда основана на Linux. Я знаю об ошибках пользовательского интерфейса Safari на Mac, но не думаю, что существуют существенные различия в JavaScript. Кроме того, я только что нашел дикое приложение: Facebook использует window.name для своего API входа в систему.   -  person Rob W    schedule 14.05.2012
comment
Только что протестировано: jsfiddle.net/NMdLU/1 отлично работает в Chrome 1–20, Safari 3.2. 3-5.1.5, Opera 9.00-12.00 и Firefox 1-12. В IE6 для добавления события load необходимо использовать attachEvent. После этого вы обнаружите, что window.name не сохраняется при изменении местоположения, установив src iframe в IE 6, 7, 8, 9 и 10PP4. Эта простая демонстрация показывает, что установка SRC сбрасывает window.name.   -  person Rob W    schedule 14.05.2012
comment
@RobW спасибо, это действительно полезно, а ФБ обнадеживает. Должен быть какой-то обходной путь для IE, я посмотрю, смогу ли я что-то выяснить, и отчитаюсь. Может что-то с history. Вы уверены, что contentWindow работает в IE? В моей последней скрипте (последняя ссылка в вопросе) я избавился от contentDocument и contentWindow, думая, что это может поддерживаться не везде. Кстати, ошибки Safari, о которых я думал, были такими вещами, как XHR, диапазоны и странности событий...   -  person Dagg Nabbit    schedule 15.05.2012
comment
@DaggNabbit, не могли бы вы ответить на мой связанный вопрос: stackoverflow.com/questions/19487729/ ?   -  person Royi Namir    schedule 21.10.2013
comment
Подход используется на thomasfrank.se/sessionvars.html.   -  person Brett Zamir    schedule 06.02.2014
comment
@DaggNabbit, что вы в конечном итоге узнали об этом подходе? Мы ищем способы заставить 2+ расширения браузера общаться друг с другом в пустом пространстве до того, как DOM будет построен (например, мы не можем использовать div на странице), и window.name выглядит так. может быть интересным претендентом... (Я знаю, что многие платформы расширений имеют API для обмена сообщениями; мы не можем использовать его, потому что расширения не будут знать адреса друг друга. Мы пытаемся выяснить, как передавать адреса друг другу .)   -  person MrChrisRodriguez    schedule 25.06.2014
comment
@MrChrisRodriguez, похоже, это отлично подойдет для того, что вы делаете, но вы также можете заглянуть в postMessage.   -  person Dagg Nabbit    schedule 25.06.2014


Ответы (2)


window.name не особенно хорош в качестве транспорта, так как (насколько мне известно) он не запускает никаких событий при его изменении. В результате приложение, пытающееся использовать window.name в качестве двустороннего канала связи, должно будет опрашивать его на наличие обновлений.

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

person Community    schedule 12.05.2012
comment
Забавно, я как раз думал о мероприятии. ISTM, что что-то вроде myIframe.onload = finishRequest; myIframe.src='somehost.com/api/?id=123' должно работать нормально... - person Dagg Nabbit; 13.05.2012
comment
Я добавил к вопросу пример, основанный на событиях. Вы это имели в виду? Есть ли что-нибудь еще, что вы можете придумать, что может сделать его не очень хорошим транспортом данных? - person Dagg Nabbit; 13.05.2012
comment
@AwalGarg Вы не можете отправлять события в окно из другого источника. - person ; 30.10.2015

Более того, может ли кто-нибудь дать мне вескую причину, почему я не должен использовать winow.name в качестве транспорта данных?

Хотя window.name может быть истинным спасителем, когда дело доходит до переноса данных между доменными изменениями, причина, по которой его нельзя использовать в качестве реального универсального механизма передачи данных, заключается в отсутствии API для хранения и извлечения данных. Например, localStorage предоставляет setItem, getItem. Такой API необходим, чтобы абстрагироваться от того, как на самом деле хранятся значения, и предотвратить конфликты форматов (которые могут возникнуть, если разные библиотеки, работающие на вашей стороне, будут хранить данные в разных форматах).

Насколько я могу судить, window.name не прижилось в качестве транспорта данных. Интересно, правильно ли мое восприятие (отсюда и исходный вопрос), и если да, то интересно, почему это так.

Поскольку window.name не предоставляет такой уровень абстракции хранения/извлечения — как описано в моем пункте выше — сторонние библиотеки не могут знать, какой формат использовать при хранении данных в window.main, и, следовательно, никогда не будут использовать window.main, поскольку он ненадежен. Если бы вы (то есть ваша основная программа) были единственными, кто читал или писал в window.name, вы могли бы решить хранить данные в формате json и соответственно сохранять/извлекать. Но что, если сторонняя библиотека также хотела что-то сохранить/получить и решила не использовать json, а вместо этого использовать другой из множество форматов сериализации... это может случайно нарушить ваш формат json и определенно вызвать проблемы.

person B12Toaster    schedule 12.09.2018