Запуск приложения Meteor в iframe из другого домена

После нескольких недель работы я наконец-то был готов развернуть свое приложение, чтобы узнать, что метеор не работает в iframe. Он отлично работает, когда окно верхнего уровня и iframe работают в одном домене, но не тогда, когда домены отличаются. Ошибка, которую я получаю в Chrome:

Uncaught SecurityError: Access to 'sessionStorage' is denied for this document. 

После этой ошибки инициализация Meteor, похоже, прекратится, и даже не будет определено даже Meteor.

После некоторого рытья я нашел эту ссылку и объяснение: http://www.w3.org/TR/webstorage/#user-tracking : " Блокирование стороннего хранилища Пользовательские агенты могут ограничивать доступ к объектам localStorage сценариям, происходящим в домене документа верхнего уровня контекста просмотра, например, лишать доступ к API для страниц из других доменов, работающих в iframe. "

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

Есть ли способ обойти это?

Изменить 2014-01-07: Я попробовал обернуть некоторые из мест, где исключения были выброшены в блоки try-catch, но у них сложилось впечатление, что это слишком сильно искажает метеор, так что он не будет правильно инициализироваться по другой причине.

Ответы

Ответ 1

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

Я создал пустое приложение:

метеорит создает testapp

то я добавил модуль политики браузера:

meteor добавить браузер-политику

Затем я редактировал testapp.js, чтобы использовать Session:

if (Meteor.isClient) {
  Template.hello.greeting = function () {
    return Session.get( 'welcome_text' );
  };

  Template.hello.events({
    'click input' : function () {
      // template data, if any, is available in 'this'
      if (typeof console !== 'undefined')
        console.log("You pressed the button");
        Session.set( 'welcome_text', 'Hello: ' + Math.random() );
    }
  });
}

if (Meteor.isServer) {

  BrowserPolicy.framing.allowAll();

  Meteor.startup(function () {
    // code to run on server at startup
  });
}

Я создал два виртуальных хоста nginx:

server {

    listen 80;
    server_name test1.com;

    location / {
        proxy_pass http://127.0.0.1:3000/;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }

}


server {

    listen 80;
    server_name test2.com;

    location / {
        alias /websites/test2.com
    }

}

test1 - приложение метеора, а test2 - iframe.

Для test2 я создал /websites/test 2/index.html:

<iframe src="http://test1.com">

Затем я добавил test1.com и test2.com в файл моих хостов и начал приложение meteor.

Я пошел в http://test2.com в браузере, и все работает так, как ожидалось. Похоже, вы пробовали эти шаги более или менее, но ваш стек приложения или сервера может иметь другие компоненты, которые мешают политике браузера.

Я бы начал с обновления вашего вопроса, чтобы включить заголовки запроса и ответа для приложения метеоров. Кроме того, ваше приложение meteor работает за прокси?

Ответ 2

Насколько я знаю, короткий ответ на ваш вопрос - нет. Я не думаю, что есть способ манипулировать переменными сеанса через iFrame. Я думаю, что это вещь безопасности. Если вы дадите причину, по которой вам нужен iFrame и/или его контекст, я могу попытаться найти решение, которое работает вокруг него, но я не думаю, что это можно сделать только с iFrames.

EDIT: на основе того, что вы сказали, похоже, что вам нужен API. Пакет, который я предлагаю для этого, называется RestStop2, что позволяет вам создавать простые RESTful API с помощью Meteor. Проверьте это.