发送多个应用程序协议请求(类似于mailto :)

时间:2012-02-27 21:39:00

标签: php javascript jquery header protocols

我使用的应用程序创建了自己的协议,就像MS为其MSN客户端msnim:chat?contact=test@test.com

所做的那样

但是,我需要创建一个PHP或javascript(或组合)来基本上尽快向协议发送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:更新了MSN而不是AIM链接,以便更加通用于测试,并包含jquery示例和JSbin

编辑2:更新为mailto链接

2 个答案:

答案 0 :(得分:10)

以下HTML / JavaScript代码会观察<a id="click_me">上的点击,并为URL创建两个新的iFrame,这可以触发您创建的自定义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代码将显示在这些iFrame中:

<?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;

Tested under Safari and Chrome,这会在点击链接时打开多个IM窗口。显然调整到令你满意。

答案 1 :(得分:8)

更新

正如BHare指出的那样,“多种弹出式”方法似乎都不适用于最新版本的Chrome。这背后的原因是他们检测到“用户启动的”操作,而不是用不想要的窗口潜在地恶意充斥用户屏幕。

从本质上讲,Chrome会允许您在每次点击活动中触发不超过一次弹出窗口。 click事件也必须是唯一的,因此它不能触发将显示弹出窗口#1的处理程序,传播到父级并触发另一个将显示弹出窗口#2等的处理程序。

另一次失败的尝试是通过尝试分发弹出窗口(主页面启动弹出窗口A启动弹出窗口B启动弹出窗口C等) - 这被认为是非用户启动的操作,并且最终只有一个协议调用允许的。

遗憾的是,此行为不受可编辑策略的控制,即无法通过允许基于原始域的弹出窗口来调整此行为。

根据部署细节(即内联网与互联网),您可以为Chrome编写一个initiate the popups at chrome level扩展名(意为浏览器chrome ,实际上是任何内容/样式/脚本)存在之外且在任何单个页面之上)。反过来,您的页面可以检测自定义附加组件的可用性,并将“三重链接”引导到该扩展名,或者提示最终用户安装附加组件。看看你如何无法修改目标协议链接的行为(例如,将指令组合成一个类似于 href =“mailto:first @ email.com,second @ email.com的调用,第三个@ email.com“)这可能是您在此阶段可用的唯一选择。

原始答案:

特定于协议的链接在客户端也可以正常工作,而永远不会进入服务器;你可以在运行时添加一个iframe,并设置正确的src。

首先,让我们好好照顾标记。贬低必须手动为点击功能分配网址。我已经完成了第一种有效且有意义的方式(以html验证为代价),但你可以更整洁并使用自定义数据 - *属性:

<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元素并将属性映射到它,并通过附加到body来“运行”它。

在这里完成:http://jsfiddle.net/uaLVh/ - 额外奖金包括隐藏辅助iframe的一些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");
}