【问题标题】:Send multiple application protocols requests ( Similar to mailto: )发送多个应用协议请求(类似于 mailto: )
【发布时间】:2012-08-15 06:01:30
【问题描述】:

我使用的应用程序创建了自己的协议,例如 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 链接

【问题讨论】:

  • 那么,问题是什么?您似乎有一个建议的解决方案,但没有说明它有任何问题。
  • 那么你的 JSBin not 做了什么?
  • 哦,这不是概念证明,是吗? :-) 我会更新我的答案,但我相信 iFrame 就是答案。
  • @BHare:我不明白为什么你必须通过 PHP - 你会做一些跟踪等吗?否则我假设这是可选的
  • @BHare:由于安全违规,较新版本的 Chrome 出现问题;每次用户交互(即点击)只允许一个导航操作 - 重新路由相同的事件以再次触发或设置较长的超时没有帮助

标签: php javascript jquery header protocols


【解决方案1】:

以下 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 窗口。显然调整到您的满意。

【讨论】:

  • 不错的方法,但它不适用于我正在使用的软件,也不适用于 mailto: 链接。这是我演示邮件的 JSBIN:链接jsbin.com/eborog/6/edit
  • 这适用于我在 Firefox、Safari 和 Chrome @BHare 下...唯一不起作用的是链接被关注,因此第二封电子邮件无法打开。如果你prevent the default action 应该可以解决这个问题...
  • 奇怪,我无法让它与 chrome 一起使用,我还没有为 ff 或 ie 烦恼。运行 chrome 17 windows 7 premium 64 位:它的视频在这里不起作用:screenr.com/wwT8(这是您的默认设置)
  • 嗯...这可能是 Windows 问题或 Outlook 问题。我在 OS X 下使用 Chrome/Safari/Firefox 和 Thunderbird 进行了测试。如果您使用 goim: URIs 而不是 mailto: UIRs,它对您有用吗?
  • 使用aim:协议也有同样的效果。奇怪的是,它可以在 IE 中同时使用 mailto:aim:。我在 Firefox 中尝试过,起初它可以工作,但后来它和 chrome 一样,只给了我第一个。
【解决方案2】:

更新:

正如 BHare 所指出的,“多重弹出”方法似乎都不适用于最新版本的 Chrome。其背后的原因是他们检测到“用户发起的”操作,而不是潜在的恶意用户屏幕被不需要的窗口淹没。

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

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

不幸的是,这种行为不受可编辑策略的控制,即不能通过允许基于源域的弹出窗口来调整它。

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

原答案:

特定于协议的链接在客户端也可以正常工作,而 永远 无需访问服务器;您可以在运行时使用正确的 src 集添加一个 iframe。

首先,让我们好好照顾标记。必须手动将 url 分配给点击功能,这是有辱人格的。我已经完成了第一种可行且有意义的方法(以 html 验证为代价),但您可以更整洁并使用自定义 data-* 属性:

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

你知道还有什么是贬低的吗?必须手动绑定点击功能——这需要太多的努力。 如果有两个这样的锚点呢? 让我们告诉 jQuery 将点击事件绑定到使用此协议的每个链接:

$('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/ - 额外的奖励包括一些用于隐藏辅助 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");
}

【讨论】:

  • 首先让我感谢您抽出时间来构建如此美丽而简单的响应。您的解决方案确实会添加到将来查看此消息的任何人以供参考。但是,在我的具体情况下,chrome 仍然无法与您的示例一起使用。我什至尝试过 chrome dev 频道。证明:youtube.com/watch?v=A9yLw4c_JTM
  • @BHare:我设法在 Mac Chrome 上重现了这个问题——据我所知,这是由用户发起的位置更改的安全限制引起的(即一键单击 = 一键更改而不是三键)。我的问题是,你能通过修改协议链接来实现这个功能吗?例如你可以做 href="mailto:first@email.com,second@email.com,third@email。 com";您的应用程序使用的协议是否支持类似的语法?这将有效地放弃对多个 iframe 等的需求。
  • 不,如果可以的话,我的生活会轻松很多。
  • 我想当它被点击并且他们有 chrome 时,我只需要输入“Not working in chrome”。我希望有人知道一种适用于 chrome 的替代方法。
猜你喜欢
  • 1970-01-01
  • 2015-04-13
  • 1970-01-01
  • 1970-01-01
  • 2015-04-27
  • 1970-01-01
  • 1970-01-01
  • 2012-06-08
  • 1970-01-01
相关资源
最近更新 更多