我正在为我的用户开发一个模态/弹出系统,以便嵌入他们的网站,与KissInsights和Hello Bar(例如here和here)一样。
构建此类服务的最佳做法是什么?看起来用户嵌入了一些JS,但该代码会插入额外的脚本标记。
我想知道它如何与Web服务通信以获取用户的内容等。
TIA
答案 0 :(得分:9)
你是对的,通常它只是客户嵌入其网站的脚本。然而,之后发生的事情有点复杂。
首先要说的是在目标页面上有一个脚本。
本质上,这个脚本只是一段JavaScript代码。它与您在自己的页面上的内容非常相似。
此脚本应在您希望显示的客户页面上生成内容。
但是,您需要考虑以下事项:
addEventListener
或addEvent
,因为这些允许您拥有多个侦听器这些规则适用于您在客户网站上直接运行的任何脚本或内容。如果您创建iframe并在那里显示您的内容,则可以在框架内的任何内容中忽略这些规则。
您的可嵌入脚本通常应由服务器上的脚本生成。这允许您包括逻辑,例如根据参数选择要显示的内容,或者应用程序数据库中的数据。
这可以用你喜欢的任何语言写成。
通常,您的脚本网址应包含某种标识符,以便您知道要显示的内容。例如,您可以使用该ID来告知客户的网站或其他类似的内容。
如果您的应用程序要求用户登录,您可以像平常一样处理此问题。其他网站调用服务器端脚本的事实没有区别。
这也有一些技巧。
如您所知,XMLHttpRequest在不同的域中不起作用,因此您无法使用它。
从其他站点发送数据的最简单方法是使用iframe并让用户在iframe中提交表单(或在框架内运行XMLHttpRequest,因为iframe的内容驻留在您自己的服务器上,所以那里是没有跨域通信)
如果嵌入式脚本在iframe对话框中显示内容,则可能需要能够告知客户站点上嵌入的脚本何时关闭iframe。这可以通过使用window.postMessage
对于postMessage,请参阅http://ejohn.org/blog/cross-window-messaging/
有关跨域通信,请参阅http://softwareas.com/cross-domain-communication-with-iframes
答案 1 :(得分:2)
您可以查看here - 这是使用我的JsApiToolkit创建的API示例,该框架允许服务提供商轻松创建和分发类似Facebook Connect的工具到第三方网站
该库建立在easyXDM之上,用于跨域消息传递,并通过模式对话框或弹出窗口促进交互。
代码和自述文件应该足以解释事物是如何组合在一起的(一旦你抽象出像XDM这样的东西,它真的不会太复杂。)
关于嵌入本身;您可以直接执行此操作,但大多数服务使用“引导”脚本,可以轻松更新以指向真实文件 - 这个小文件可以使用缓存编译指示,以确保它不会缓存太长时间,而注入的文件可以作为长文件提供。
这样,您只会产生重新下载引导程序而不是整个脚本集的开销。
答案 2 :(得分:1)
最佳做法是尽可能少地将代码放入代码段中,这样您就不必要求用户更新代码。例如:
<script type="text/javascript" src="http://your.site.com/somecode.js"></script>
如果作者将其嵌入其页面,则工作正常。否则,如果您需要书签,可以使用此代码在任何页面上加载脚本:
javascript:(function(){
var e=document.createElement('script');
e.setAttribute('language','javascript');
e.setAttribute('src','http://your.site.com/somecode.js');
document.head.appendChild(e);
})();
现在您的所有代码都将存在于上面引用的URI中,并且无论何时加载它们的页面,都会下载并执行您的代码的新副本。 (不考虑缓存设置)
从该脚本中,只需确保不破坏名称空间,并在加载另一个库之前检查库是否存在。如果您使用的话,请使用安全jQuery
对象而不是$
。如果你想加载更多的外部内容(比如jQuery,UI东西等),可以使用onload
处理程序来检测它们何时被完全加载。例如:
function jsLoad(loc, callback){
var e=document.createElement('script');
e.setAttribute('language','javascript');
e.setAttribute('src',loc);
if (callback) e.onload = callback;
document.head.appendChild(e);
}
然后你可以简单地调用这个函数来加载任何js文件,并执行一个回调函数。
jsLoad('http://link.to/some.js', function(){
// do some stuff
});
现在,与您的域通信以检索数据的一种棘手的方法是使用javascript作为传输。例如:
jsLoad('http://link.to/someother.js?data=xy&callback=getSome', function(){
var yourData = getSome();
});
您的服务器必须动态处理该路由,并返回一些具有“getSome”功能的javascript,该功能可以满足您的需求。例如:
function getSome(){
return {'some':'data','more':'data'};
}
这将非常有效地允许您与服务器进行通信,并从服务器可以获取数据的任何位置处理数据。
答案 3 :(得分:0)
您可以提供动态生成(用于例如PHP或Ruby on Rails)以在每个请求上生成此文件)来自您的服务器的JS文件,该文件是从客户网站导入的,如下所示:
<script type="text/javascript" src="//www.yourserver.com/dynamic.js"></script>
然后,您需要为客户提供一种方式来决定他们想要包含模式/弹出窗口的内容(例如文本,图形,链接等)。您可以创建一个简单的CMS,也可以手动为每个客户执行此操作。
您的服务器可以看到每个JS文件请求的来源,并根据它提供不同的JS代码。例如,JS代码可以将HTML代码插入到客户网站中,在顶部创建一个带有文本和链接的栏。
如果您想访问您的客户访问者信息,您可能需要从HTML代码中读取它,让您的客户以特定方式提供您想要的信息,或者找出从每个客户Web服务器访问它的不同方式。