构建小部件时隐藏Javascript

时间:2011-12-06 19:13:44

标签: javascript html user-interface widget

我正在构建一个非常容易集成的Web小部件。假设http://www.bicycleseller.com/想要将我的小部件集成到他的网页上。他所要做的就是将以下内容复制并粘贴到他页面的头部:

<script src="http://www.widgetprovider.com/widget.js" type="text/javascript"></script>
<script>
Widget.create("123456accessKeyOfBicycleSeller").render("myWidget");
</script>

<div id="myWidget"></div>到身体部分的任何位置。小部件将显示在该div中。

作为窗口小部件提供程序,我托管 widget.js

var Widget = new function () {

    this.url = "www.widgetprovider.com/widget.jsp";
    this.name = "";
    this.parameters = "width=400,height=200,screenX=750,screenY=300,resizable=0";


    this.create = function (accessKey) {
        this.accessKey = accessKey;
        return this;
    };


    this.render = function (divId) {
        // make sure the document is fully loaded and place the widget on BicycleSellers page.
        // when the widget (a jpeg) is clicked, a jsp page I host will popup.
        window.onload = function () {
            document.getElementById(divId).innerHTML = '<img src="images/widget-image.jpg" onclick="Widget.display()"/>';
        };
        return this;
    };

    this.display = function () {
        // open a popup window that displays a page I host.
        var popup = window.open(this.url + "?accessKey=" + this.accessKey, this.name, this.parameters);
        popup.focus();
        return this;
    };
};

因此,BicycleSeller将小部件放在他的页面上,当用户点击它时,会出现一个弹出窗口,显示来自我托管的页面的内容。 但是,每个想要嵌入我的窗口小部件的网站管理员都必须提供一个accessKey,这是唯一的,因为弹出窗口的内容将取决于它。

我的问题是:

1)在这种情况下,任何前往bicycleseller.com并查看HTML源代码的人都可以看到他的accessKey在头部区域进行了硬编码。然后他们可以导航到www.widgetprovider.com/widget.jsp?accessKey=123456。我不希望这种情况发生。关于这个还能做什么?例如;我在看Facebook的来源,他们似乎很好地隐藏了一切。

2)这是继续构建小部件的好方法吗?我想的是一个灯箱而不是一个弹出窗口(可能会被一个弹出窗口拦截器阻挡 - 尽管在这个例子中没有)。欢迎任何意见/建议。

3)如果我尝试放置小部件并编写Widget.create("key1").render("div1"); Widget.create("key2").render("div2");,则会生成两个图像。但点击后,两个弹出窗口都会显示key1个信息。这是因为Widget中的widget.js类是单身。如果我不将它设为单身,那么我就无法放置图像的onclick属性(Widget.display())。我该怎么做?

寻求三个问题的帮助。任何帮助将不胜感激。感谢。

4 个答案:

答案 0 :(得分:1)

您的服务器可以验证请求的“Referer”标头。这将阻止临时用户通过在地址栏中输入URL或通过遵循第三方链接来查看超出上下文的弹出内容。标题可能是欺骗性的,但这需要一些努力,而不是标准的浏览器功能。

您将无法阻止黑客在自己的计算机上加载弹出窗口。

关于弹出窗口是一个好主意的问题,我认为内联更好,但也更多的工作和更少的可移植性,所以你必须决定弹出窗口是否足够好。

要使Widget不是单身,而不是:

$(window).load(function () {
    document.getElementById(divId).innerHTML = '<img src="images/widget-image.jpg" onclick="Widget.display()"/>';
});

使用:

var widget = this;
$(window).load(function () {
    var image = document.createElement("img");
    image.src="images/widget-image.jpg";
    image.onclick = function() { widget.display() };
    document.getElementById(divId).appendChild(image);
});

通过将onclick设置为实际函数而不是函数代码,您可以通过闭包返回Widget实例。

答案 1 :(得分:1)

我认为你应该指出这样一个事实:你的小部件 - 基于javascript - 可以被缓存,并且(即使没有缓存)客户端也能够查看源代码。毕竟,javascript是在客户端计算机上执行的,而不是在您的服务器上执行。

要“隐藏”您想要执行的操作,您必须注意让服务器端脚本处理“敏感数据”。客户可以下载的所有内容都可以被客户查看和搞砸。他们唯一不能得到的就是你服务器上“幕后”的东西。因此,如果您想隐藏任何内容,请将其保留在您的服务器上。

使用javascript可以获得的唯一安全级别是“混淆”。但这几乎是任何投资了一点时间的人都可以解除的安全水平。 (阅读:脚本小孩会喜欢扭转这样的东西,因为它的乐趣!)

答案 2 :(得分:0)

关于你的第一个问题,我认为@JWeWeissman已经给出了一个可能的解决方案。

在回答您的第二个问题时,我不相信弹出窗口拦截器会阻止用户启动点击打开弹出窗口。我相信阻止者正在寻找无论用户在页面上采取什么操作而运行的代码。制作自己喜欢弹出窗口的灯箱相当容易,但可能不值得花时间,特别是因为您无法控制嵌入的页面。他们可能会以与灯箱类型弹出解决方案不兼容的方式嵌入Flash,这可能会让您头疼。

在回答你的第三个问题时,我会在每次“创建”一个小部件时这样做,你实际上创建了一个代表它的对象。您可以在数组中的Widget对象中跟踪这些小部件“实例”。您还可以在window.onload方法上实例化,该方法循环遍历“实例”,并为每个单击方法提供将触发实例accessKey的方法。我也摆脱了创建和渲染之间的分离,因为你似乎把它们召集在一起。所以这是一种方法:

var Widget = new function () {
        var widgets = [];
        this.url = "http://www.yahoo.com";
        this.name = "";
        this.parameters = "width=400,height=200,screenX=750,screenY=300,resizable=0";

        window.onload = function () {
            var w;
            for (w = 0; w < widgets.length; w++) {
                document.getElementById(widgets[w].id).innerHTML = '<img src="images/widget-image.jpg" onclick="Widget.display(' + w + ')"/>';
            }
        };

        this.display = function (index) {
            widgets[index].display();//display the widget instance corresponding to the index
        }

        this.create = function (accessKey, elId) {
            var newWidget = {
                accessKey: accessKey,
                id: elId,
                display: function () {
                    // open a popup window that displays a page I host.
                    var popup = window.open(Widget.url + "?accessKey=" + accessKey, Widget.name, Widget.parameters);
                    popup.focus();
                }
            };

            widgets.push(newWidget);

            return newWidget;
        };


    };

答案 3 :(得分:0)

我不知道2和3,但我可以回答1。

您可以做什么:阻止人们查看您的源代码。一切都可以被欺骗,你可以阻止随便的用户,但你不会让一个坚定的人停留超过几秒钟(是的,秒)。您可以做的是阻止人们在其网站上使用您的代码。

您可以制作在您控制的宽限期后自行失效的链接。例如:

$key = "client_key";
$time = $_SERVER['REQUEST_TIME'];
$hash = md5("nonce" . $key . $time);    // super secret method than no one should ever find out
return return "hash=" . $hash . "&key=" . $key . "&time=" . $time;

这确实要求您在客户的网站上放置服务器端代码。散列确保没有人可以“混乱”变量,因为没有人知道你用于散列的方法(选择一些更加模糊的东西,添加一个合适的随机数)。 time变量可用于拒绝具有非常旧time值的请求,例如:24小时。

但是,你不能阻止人们一次获取代码并为自己保留一份本地副本,但至少你已将它们从更新和错误修复中排除。

您还可以添加模糊处理,以便他们无法轻松修改维护代码。

没有办法完全阻止人们“窃取”您的JavaScript。