Отправить несколько протоколов запросов приложений (аналогично mailto:) - PullRequest
8 голосов
/ 28 февраля 2012

Я работаю с приложением, которое создало собственный протокол, такой как MS, для своего клиента MSN msnim:chat?contact=test@test.com

Однако мне нужно создать PHP или javascript (или combo), чтобы в основном посылать 3 запроса к протоколу как можно скорее. Я также хочу, чтобы конечный результат был www.test.com/send.php, чтобы пользовательская ссылка <a href='www.test.com/send.php'> не всплывала или не перенаправляла на страницу, как если бы она делала

<?php header('Location: msnim:chat?contact=test@test.com'); ?> не будет создавать новую страницу или перенаправлять по нажатию пользователем href

Вот JQUERY и JSBin моего доказательства концепции

http://jsbin.com/etubas/11/

$(document).ready(function(){
    $("a#click_me").click(function(){
        setTimeout(function(){
            console.log('test ran');
            window.location = 'mailto:test@test.com';
        }, 100);
        setTimeout(function(){
            console.log('new ran');
            window.location = 'mailto:new@new.com';
        }, 200);
    });
});

Кажется, это нормально работает с IE9 и насколько я вижу IE8. Firefox 10, похоже, тоже в порядке, но Chrome 17 отправляет только 1-е письмо.

Редактировать 1: обновлен MSN вместо ссылок AIM, чтобы сделать его более универсальным для тестирования и включать пример jquery и JSbin

Редактировать 2: обновлено до почтовых ссылок

Ответы [ 2 ]

10 голосов
/ 28 февраля 2012

Следующий код HTML / JavaScript будет отслеживать клики на <a id="click_me"> и создавать два новых iFrames для URL, которые могут активировать созданную вами пользовательскую схему URI:

<html>
<head>
<script type="text/javascript">
$(document).ready(function(){

    var imURL = 'http://josh.gitlin.name/9472703.php?id='; // Change this to your URL

    function openIM(who) {
        var iFrame = '<iframe src="'+imURL+who+'"></iframe>';
        $('div#imLinks').append(iFrame);
    }

    $("a#click_me").click(function(e){
        e.preventDefault();
        setTimeout(function(){
            openIM('1');
        }, 100);
        setTimeout(function(){
            openIM('2');
        }, 200);
    });
});​
</script>
</head>
<body>
    <p>Some content here</p>
    <p><a href="#" id="click_me">Click Me!</a></p>
    <div id="imLinks"></div>
</body>
</html>​

Следующий код PHP будет отображаться внутри этих iFrames:

<?php

$screenname = '';

switch($_REQUEST['id']) {
        case '1': $screenname = 'firstPerson'; break;
        case '2': $screenname = 'secondPerson'; break;
        default: $screenname = 'otherPerson'; break;
}

echo <<<END_OF_HTML 
<html>
<head>
<meta http-equiv="refresh" content="0;url=aim:goim?screenname=$screenname">
</head>
</html>
END_OF_HTML;

Протестировано в Safari и Chrome , при нажатии ссылки открывается несколько окон чата. Очевидно, настроить к вашему удовлетворению.

8 голосов
/ 07 марта 2012

Обновление:

Как указывает BHare, ни один из подходов с несколькими всплывающими окнами не работает в последних версиях Chrome. Причиной этого является обнаружение действий, инициируемых пользователем, в отличие от потенциально злонамеренного затопления пользовательских экранов нежелательными окнами.

По сути, Chrome позволит вам вызывать не более одного всплывающего окна на событие клика. Событие click также должно быть уникальным, поэтому оно не может вызвать обработчик, который покажет всплывающее окно # 1, распространится на родительский элемент и вызовет другой обработчик, который покажет всплывающее окно # 2 и т. Д.

Еще одна неудачная попытка была предпринята при попытке распространения всплывающих окон (главная страница инициирует всплывающее окно A, которое запускает всплывающее окно B, которое запускает всплывающее окно C и т. Д.) - это было признано действием, не инициированным пользователем, и в конечном итоге был только один вызов протокола допускается.

К сожалению, это поведение не контролируется редактируемой политикой, т. Е. Ее нельзя изменить, разрешив всплывающие окна на основе домена происхождения.

В зависимости от особенностей развертывания (т. Е. Интрасеть или интернет) вы можете закодировать расширение для Chrome, которое будет инициировать всплывающие окна на уровне Chrome (что означает браузер Chrome , эффективно любой контент / стиль / сценарий, который существует за пределами и выше любой отдельной страницы). Ваша страница, в свою очередь, может определять доступность настраиваемой надстройки и направлять «тройные ссылки» на это расширение или предлагать конечному пользователю установить надстройку. Видя, как вы не можете изменить поведение ссылок целевого протокола (например, путем объединения инструкций в один вызов, аналогичный тому, что был href = "mailto: first @ email.com, second @ email.com , третий @ email.com ") это может быть единственным вариантом, доступным вам на данном этапе.

Оригинальный ответ:

Ссылка для протокола будет работать так же хорошо на стороне клиента без когда-либо доступа к серверу; Вы можете просто добавить iframe во время выполнения с правильным набором src.

Во-первых, давайте хорошо позаботимся о разметке. Это унизительно, когда приходится вручную назначать ссылки на функции кликов. Я сделал это первым способом, который работал и имел смысл (ценой проверки HTML), но вы могли бы быть аккуратнее и использовать пользовательские атрибуты data- *:

<a href="mailto:first@tempinbox.com" href2="mailto:second@tempinbox.com" href3="mailto:third@tempinbox.com">Click me!</a>​

Вы знаете, что еще унижает? Необходимость вручную связывать функции щелчка - это требует слишком много усилий. А что если бы было два таких якоря? Давайте просто скажем jQuery привязать событие click к каждой ссылке, использующей этот протокол:

$('a[href^="mailto:"]').bind("click", function(e){
    /*Do stuff*/
});

Перед тем, как перейти к атрибутам href ~ href3 , давайте напишем функцию, которая будет обрабатывать открытие отдельных ссылок mailto:

function openMailto(s){
    if (s) $("<iframe />", {src:s, class:"mailto-iframe"}).appendTo("body");
}

Он проверяет, что URL передается из непустого атрибута, динамически создает элемент iframe, сопоставляет с ним атрибуты и «запускает» его, добавляя в тело.

Завершено здесь: http://jsfiddle.net/uaLVh/ - дополнительные бонусы включают в себя некоторые CSS, чтобы скрыть вспомогательные фреймы и стилизовать ссылки для протокола. И да, я знаю, что обещал перебрать атрибуты href, но я только что сделал это вручную.

HTML

<a href="#">Don't click me</a><br/>
<a href="mailto:first@tempinbox.com" href2="mailto:second@tempinbox.com" href3="mailto:third@tempinbox.com">Click me!</a>​

CSS

/*prevent these iframes from being visible*/
iframe.mailto-iframe{display:none;}

/*bonus: style your protocol-specific links*/
a[href^="mailto:"] {padding-left:20px;background:url(http://sstatic.net/stackoverflow/img/favicon.ico) no-repeat;}
​

JS

$('a[href^="mailto:"]').bind("click", function(e){
    //cache "this" link element jquery reference
    $this=$(this);

    //remove "helper" iframes if any, you don't want to end up with 300 iframes by accident!
    $("iframe.mailto-iframe").remove();

    //go wild... you could have a nice loop as you're not limited to 3 hrefs
    openMailto($this.attr("href"));
    openMailto($this.attr("href2"));
    openMailto($this.attr("href3"));

    //processing href2 and href3 before allowing the default action to happen firstseemed counter-intuitive
    e.preventDefault();
    return false;
});
function openMailto(s){
    if (s) $("<iframe />", {src:s, class:"mailto-iframe"}).appendTo("body");
}
...