Идеальное решение для использования и анализа внешнего междоменного интерфейса easyXDM

внешний интерфейс JavaScript

Междоменные проблемы внешнего интерфейса — относительно распространенные проблемы на крупных веб-сайтах. В этой статье подробно представлены основные сведения и сведения об использовании easyXDM для решения междоменных задач переднего плана. Конкретное использование может быть расширено на основе примеров кода в статье.

0. Фон

Из-за захвата HTTP отдельными сетевыми операторами сторонние рекламные объявления вставляются в некоторые важные всплывающие окна iframe на веб-сайте, а контент полностью блокируется, что серьезно влияет на работу пользователей. Компания приняла решение перевести эти страницы на HTTPS. После переключения было обнаружено, что функция исходного плавающего слоя iframe для автоматической адаптации к размеру недействительна. Причина заключалась в том, что главная страница была HTTP. Ограничение устройств не может работать. . Поэтому для решения этой ситуации необходимо междоменное решение.

1. Междоменные проблемы

Расскажите, что такое междоменная проблема? Когда запрос и передача данных происходит между страницами веб-сайта, если любой из протоколов имени протокола, хост-хоста и номера порта в двух URL-адресах отличается, это представляет собой междоменный. По умолчанию междоменные страницы не могут напрямую манипулировать объектами страниц друг друга через JavaScript.

Простое сравнение различных междоменных решений выглядит следующим образом:

Вышеупомянутые различные междоменные решения не раскрываются в этой статье. Заинтересованные студенты могут обратиться к «Углубленное понимание методов и принципов междоменного интерфейса» (blog.CSDN.net/Стюардесса/AR…).

Здесь мы сосредоточимся на рекомендации easyXDM, потому что easyXDM интегрирует различные существующие кросс-доменные решения и хорошо реализует такие функции, как кросс-браузерная совместимость, параллельная междоменная связь, белый список междоменных запросов и ответ на связь, Он может решать различные сценарии приложений. междоменного использования.

2. Пример использования EasyXDM

родительская страницаindex.htmlОсновной код:

<div id="container"></div>
<div id="output">
    <p>蓝色区域为主页面内容输出区</p>
</div>
<script src="easyXDM.min.js"></script>
<script>
var showMsg = function (message) {
    document.getElementById('output').innerHTML += "<p>" + message + "</p>";
};
var rpc = new easyXDM.Rpc({
    isHost: true,
    remote: 'http://127.0.0.1/easyXDM/iframe.html',
    hash: true,
    protocol: '1',
    container: document.getElementById('container'),
    props: {
        frameBorder: 0,
        scrolling: 'no',
        style: {width: '100%', height: '100px'}
    }
},
{
    local: {
        echo: function (message) {
            showMsg(message);
        }
    }
});
</script>

Подстраницаiframe.htmlОсновной код:

<p>实线框为子页面区域</p>
<button id="btn" value="">点击给主页面发数据</button>
<div id="output"></div>
<script src="easyXDM.min.js"></script>
<script>
var showMsg = function (message) {
    document.getElementById('output').innerHTML += "<p>" + message + "</p>";
};
window.rpc = new easyXDM.Rpc({
    isHost: false,
    //acl: '^(https?:\\/\\/)?([a-zA-Z0-9\\-]+\\.)*baixing.com(\\/.*)?$',
    protocol: '1'
},
{
    remote: {
        echo: {}
    }
});
document.getElementById('btn').onclick = function () {
    rpc.echo('echo from iframe');
};
</script>

доступhttp://localhost/easyXDM/index.html,потому чтоindex.htmlа такжеiframe.htmlХосты двух страниц разные, а операции с подстраницами на содержимом главной страницы относятся к междоменному доступу. С easyXDM в качестве канала эта операция может выполняться нормально, и эффект показан на следующем рисунке:

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

3. Принципиальный анализ EasyXDM

3.1 Описание принципа

easyXDM инкапсулирует различные базовые схемы связи, например ту, которая использовалась в приведенном выше примере.postMessage()Схема для достижения междоменной двунаправленной связи.

3.1.1 Подстраница отправляет данные на главную страницу

easyXDM упаковывает операцию вызова метода и передаетpostMessage()Оно отправляется на главную страницу, а функция обработки сообщений главной страницы получает данные и передает их easyXDM для разбора, а затем вызывает вызывающую функцию. Вызов кода и поток данных показаны на следующем рисунке:

easyxdm request
easyxdm request

Описание переданных данных:

  • defaultXXX: идентификатор канала, это значение остается неизменным, когда страница не обновляется.
  • id: номер запроса, увеличивающийся автоматически, увеличивается на 1 каждый раз при отправке запроса.
  • method: имя вызываемого метода
  • params: параметры для вызова метода в формате JSON.
  • jsonrpc: указывает версию сообщения JSON-RPC.

3.1.2 Метод главной страницы возвращает данные ответа

easyXDM также позвонитpostMessageОтвет метода отправляется обратно на подстраницу, а функция обработки сообщений подстраницы получает данные и передает их easyXDM для синтаксического анализа, а после синтаксического анализа выполняет соответствующую операцию обработки ответа. Вызов кода и поток данных показаны на следующем рисунке:

easyxdm response
easyxdm response

Описание переданных данных:

  • defaultXXX: идентификатор канала. Когда страница не обновляется, это значение остается неизменным, оно согласуется с данными, отправленными подстраницей
  • id: то же, что и идентификатор, отправленный при вызове метода
  • result: ответ метода в формате JSON.
  • jsonrpc: указывает версию сообщения JSON-RPC.

Ниже подробно описан код главной страницы и подстраницы.

3.2 Анализ кода вызова главной страницы

вызов на главную страницуeasyXDM.Rpc()При инициализации коммуникационного компонента одновременно создается подстраница iframe; значение конкретных параметров описывается следующим образом:

  • isHost: true, что означает создание дочерней страницы iframe
  • remote: URL-адрес созданной подстраницы iframe.
  • container: значение представляет собой объект DOM, созданный iframe будет содержаться в контейнере.
  • props: содержимое, указанное в атрибуте, будет добавлено к объекту iframe.
  • hash: Если истинно, то это означает, что параметры xdm_e/xdm_c/xdm_p, относящиеся к каналу, будут записаны в хеш URL, а если ложно, то он станет параметром url; в общем случае рекомендуется установить его равным правда, потому что параметры внешнего интерфейса, связанные с междоменной связью, передаются на серверную часть, и это не очень хороший способ, но он может решить проблему удержания канала после отправки формы, поэтому выбирайте конкретные сценарии.

Установив указанные выше свойства разумно, iframe, изначально написанный на странице, может быть изменен для передачиeasyXDM.Rpc()способ загрузки, чтобы реализовать гибкое встраивание кода.

В приведенном выше примере элементы страницы после RPC-инициализации родительской страницы выглядят следующим образом:

<div id="container">
    <iframe
        name="easyXDM_default5491_provider"
        id="easyXDM_default5491_provider"
        frameborder="0"
        scrolling="no"
        src="http://127.0.0.1/easyXDM/iframe.html#xdm_e=http%3A%2F%2Flocalhost&amp;xdm_c=default5491&amp;xdm_p=1"
        style="width: 100%; height: 100%;">
    </iframe>
</div>

Имя и идентификатор iframe генерируются автоматически, чтобы различать разные каналы RPC, что означает, что на одной странице можно установить несколько каналов для междоменных вызовов. Средние параметры xdm_e/xdm_c/xdm_p — это параметры инициализированного канала.

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

3.3 Анализ кода вызова подстраницы

Разбор параметров RPC в iframe выглядит следующим образом:

  • isHost:false, значит это клиент, не создавать страницу iframe
  • protocol: Протокол связи, номер, пожалуйста, обратитесь к следующему описанию протокола связи для конкретного значения, необязательно
  • acl: белый список URL вызывающих код, необязательно

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

После того, как приведенная выше конфигурация будет правильной, междоменный вызов функции будет иметь тот же эффект, что и локальный вызов, а конкретная промежуточная связь будет обработана easyXDM, как в тексте.rpc.echo()Его уже можно вызывать прямо в определение главной страницыechoметод.

3.4 Описание протокола связи

Что касается протокола связи, если он не указан в конфигурации кода, он будет соответствовать первому в соответствии со следующими правилами.

  • 4: Прямая связь, когда оба конца связи принадлежат к одному и тому же домену.
  • 1: когда естьwindows.postMessageилиdocument.postMessage(поддерживается IE8+, Firefox 3+, Opera 9+, Chrome 2+, Safari 4+), используйтеpostMessageмеханизм связи
  • 6: Атрибут swf существует в конфигурации и поддерживаетwindow.ActiveXObject, общаться через настроенный swf
  • 5: при использовании браузера Gecko (Firefox 1+) используйтеwindow.frameElementсвойства общаться
  • 2: Когда в конфигурации есть remoteHelper, общайтесь через настроенный remoteHelper
  • 0: По умолчанию поддерживаются всеми браузерами, при несоблюдении вышеуказанных правил для связи используется механизм загрузки изображений

4. Больше функций

4.1 Добавить обработку ответа на запрос

index.htmlФункция эха страницы добавляет оператор return для возврата значения:

<script>
new easyXDM.Rpc({
    // ...
},
{
    local: {
        echo: function (message) {
            document.getElementById('output').innerHTML += "<p>" + message + "</p>";
            return {'msg': 'echo done from index'};
        }
    },
    remote: {}
});
</script>

iframe.htmlВы можете добавить функцию обратного вызова при вызове метода RPC:

<script>
// ...
document.getElementById('btn').onclick = function () {
    rpc.echo('echo from iframe', function (response) {
        showMsg(response.msg);
    }, function (errorObj) {
        alert('error');
    });
};
</script>

Результаты, как показано ниже:

4.2 Главная страница вызывает метод подстраницы

существуетiframe.htmlЗарегистрируйте метод для доступа к содержимому собственной страницы в локальном RPC.pingIframe:

window.rpc = new easyXDM.Rpc({
    // ...
},
{
    local: {
        pingIframe: function (message) {
            showMsg(message);
            return {'msg': 'pong from iframe'}
        }
    },
    remote: {
        echo: {}
    }
});

существуетindex.htmlЗарегистрируйте подстраницу в удаленном RPCpingIframeОбъявление метода, добавьте событие вызова кнопки:

<button id="btn" value="">点击给子页面发数据</button>
<script>
// ...
var rpc = new easyXDM.Rpc({
    // ...
},
{
    local: {
        // ...
    },
    remote: {
        pingIframe: {}
    }
});

document.getElementById('btn').onclick = function () {
    rpc.pingIframe('ping from index', function(response){
        showMsg(response.msg);
    }, function(errorObj){
        alert('error');
    });
};
</script>

Результаты, как показано ниже:

4.3 Главная страница взаимодействует с несколькими страницами

Чтобы сделать многостраничную коммуникацию, просто повторите похожие связанные вызовы кода. В этом примере скопируйте приведенный вышеiframe.htmlдляiframe2.htmlИ просто измените текст внутри, чтобы различать; измените одновременноindex.htmlкод показывает, как показано ниже:

<div id="container"></div>
<button id="btn" value="">点击给子页面1发数据</button>
<button id="btn2" value="">点击给子页面2发数据</button>
<div id="output">
    蓝色区域为主页面内容输出区
</div>
<script src="easyXDM.min.js"></script>
<script>
var showMsg = function (message) {
    document.getElementById('output').innerHTML += "<p>" + message + "</p>";
};
var generateRpc = function (url) {
    return new easyXDM.Rpc({
        isHost: true,
        remote: url,
        hash: true,
        protocol: '1',
        container: document.getElementById('container'),
        props: {
            frameBorder: 0,
            scrolling: 'no',
            style: {width: '100%', height: '100px'}
        }
    },
    {
        local: {
            echo: function (message) {
                showMsg(message);
                return {'msg': 'echo done from index'};
            }
        },
        remote: {
            pingIframe: {}
        }
    });
};
var bindRpc = function(rpc, btnId) {
    document.getElementById(btnId).onclick = function () {
        rpc.pingIframe('ping from index', function (response) {
            showMsg(response.msg);
        }, function (errorObj) {
            alert('error');
        });
    };
};

var rpc1 = generateRpc('http://127.0.0.1/easyXDM/iframe.html');
bindRpc(rpc1, 'btn');

var rpc2 = generateRpc('http://127.0.0.1/easyXDM/iframe2.html');
bindRpc(rpc2, 'btn2');
</script>

Результаты, как показано ниже:

4.4 Поддержание связи RPC после переключения страниц iframe

существуетhashУстановить какfalseБез дополнительной обработки, когда вы отправляете форму на подстранице или щелкаете гиперссылку на подстранице, чтобы открыть новую страницу, вы обнаружите, что связь с родительским окном не будет работать. Причина в том, что после переключения страниц теряются параметры xdm_e/xdm_c/xdm_p, относящиеся к каналу связи, что приводит к невозможности поддержания связи. Решение состоит в том, чтобы передать параметр канала в URL-адресе вновь открытой страницы. Для удобства введена библиотека jQuery, а код выглядит следующим образом:

/* 使用方法:
 * 1. 将以下代码加入到子页面中
 * 2. 在子页面的 form 或 a 标签中增加 easyxdm 类名,将 easyXDM 参数通过网址
 * 传递给新页面以保持页面跳转后跨域通信能保持
 */
$(document).ready(function () {
    $('form.easyxdm').each(function () {
        var $form = $(this);
        var action = $form.attr('action');
        $form.attr('action', action + window.location.hash);
    });
    $('a.easyxdm').each(function () {
        var $link = $(this);
        var href = $link.attr('href');
        $link.attr('href', href + window.location.hash);
    });
});

5. Отладка библиотеки easyXDM

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

  1. Из репозитория easyXDM GitHub (GitHub.com/родственники Ю Вин...) чтобы вытащить всю ветвь
  2. БудуsrcСкопируйте каталог в свой собственный каталог кода
  3. Изменить для импорта, где импортируется библиотека easyXDMeasyXDM.debug.js
  4. После этого вы можете использовать браузер Chrome для отладки JavaScript. Конкретный метод отладки не будет подробно описан в этой статье. Заинтересованные учащиеся могут обратиться к «Сводке по отладке интерфейсного браузера Chrome» (woo woo Краткое описание.com/afraid/no 25 из 5 нет 88 нет…) в разделе «Отладка точки останова» на странице ресурсов «Источники».

Загрузите полный код этой статьи:pan.baidu.com/s/1cpRlim

6. Концевые сноски

Поскольку README.md самой библиотеки easyXDM давно не поддерживается и не обновляется, значение некоторых параметров найти невозможно, в документе не объясняется принцип и реализация, автор столкнулся с множеством проблем в процессе использования, и может быть глубоко понят только путем отладки кода и чтения кода.Его принцип реализации решить. Эта статья представляет собой краткое описание использования easyXDM автором для справки.

7. Справочные документы:

  1. официальный сайт EasyXDMeasyxdm.net
  2. GitHub-репозиторий easyXDMGitHub.com/родственники Ю Вин...

автор:Нам Джи Мин
Введение: член технической группы по доходам People's Network.

Эта статья является лишь личной точкой зрения автора и не отражает позицию People's Network.
Автор заглавного изображения: Pic2.me


Эта статья была впервые опубликована в общедоступной учетной записи WeChat «Технической группы People's Network», отсканируйте код и немедленно подпишитесь: