很久很久以前,我寫了一篇KB介紹停用特定Reporting Service報表匯出格式的做法,除了修改config外,我還提出了可以透過指定Stylesheet遮蔽部分匯出選項的做法。

使用Stylesheet的做法,使用者可以透過去除URL rs:stylesheet參數讓防護手法破功,因此我在原先的KB裡只稍稍帶過,並未再花時間再深入研究。不過,日前網友草莓妹問到如何利用第二種方法,以CSS引進Javascript去更動內容。

雖然我覺得用Stylesheet去卡Reporting Service匯出選項的實用性不高,但這一招在某些只允許你改變CSS,不准變動網頁內容的場合有些用處,所以花了點時間,還是研究了一下CSS綁Javascript的做法,以備未來不時之需。

回到先前所提,我們可以用rs:stylesheet=yourCustCSS的方式套上自己寫的樣式。其中要設法將Export中不要的選項移除,我的想法是掛事件在body.onload上,在載入時觸發一段Code對下拉選單動手腳。

不幸的是,CSS加掛Javascript的做法,IE與Firefox提供的支援並不相同。IE可以很簡便的用behavior:expression(...javascript code...);表示法直接寫在CSS中(當然,要寫成HTC也OK);Firefox則必須使用XBL的做法,繞的圈子大一點,而且Reporting Service上不好直接放XBL檔案,因此得更外找地方放檔案。

CSS的寫法如下:

BODY 
{
    /* For IE */
    behavior:expression(this.onload = function() {
        var sels = document.getElementsByTagName("select");
        for (var i=0; i<sels.length; i++)
        {
            if (sels[i].title != "匯出格式") continue;
            var opts = sels[i].options;
            for (var j=0; j<opts.length; j++) 
                //Remove PDF option
                if (opts[j].value == "PDF") opts[j]=null;
        }
    });
    /* For FireFox */
    -moz-binding:url(http://another.web.server/LimitedExport.xbl#bodyEvent);
}

XBL寫起來比較囉嗦... 我試不出掛onload(也許本來就不允許),只好用onmoseover+限執行一次代替。

<?xml version="1.0"?>
<bindings xmlns="http://www.mozilla.org/xbl" xmlns:html="http://www.w3.org/1999/xhtml">
    <binding id="bodyEvent" styleexplicitcontent="true">
    <handlers>
        <handler event="mouseover">
        var flagDone = this.getAttribute("FlagDone");
        if (flagDone == null)
        {
            this.setAttribute("FlagDone", "Y");
            var sels = document.getElementsByTagName("select");
            for (var i=0; i &lt; sels.length; i++)
            {
                if (sels[i].title != "匯出格式") continue;
                var opts = sels[i].options;
                for (var j=0; j &lt; opts.length; j++) 
                    //Remove PDF option
                    if (opts[j].value == "PDF") opts[j]=null;
            }
        }
        </handler>
    </handlers>
    </binding>
</bindings>

試了一下,這樣搞下來,在IE及FireFox中都不會看到PDF選項。不過,如果User不是用加了rs:stylesheet參數的URL連起來,這些額外花的功夫頓成廢柴,規劃應用時時要留意。

PS: CSS加Javascript真是讓人又愛又恨的功能,可以用來突破某些網站不給寫Javascript的限制,但換作網站管理者的角度,這無疑又是個掛馬下毒的好後門,不可不慎。


Comments

# by 草莓妹

看到文章裡有我的名字真是不好意思@@ 非常感謝版主特地寫了這篇!! 我會試試看!! 謝謝啦!!!!

# by A MY

想請問一個問題 在URL跟.ASPX.CS中傳參數給SSRS 最後是用reportviewer顯示出報表 再點選EXCEL或是PDF另存 有沒有辦法不通過reportviewer顯示出報表 直接跳到另存PDF?

# by Jeffrey

to A MY, 我想到兩種做法: 1) 透過CSS設定將ReportViewer隱藏起來,再使用Javascript去觸發它的檔案另存鈕 2) 在aspx.cs中呼叫Report Server的Web Service,取得讓報表匯出為PDF/Excel的二進位資料(byte[]),直接讓使用者下載。

# by LED

版大您好: 請教一下, 我想要讓RS報表具有禁止使用者反白複製的功能,這部份你有沒有什麼建意呢? 我在網路上找了以下語法,只要將它加到body裡面,就可以達到這樣的效果 ONDRAGSTART="window.event.returnValue=false" ONCONTEXTMENU="window.event.returnValue=false" onSelectStart="event.returnValue=false" 但網路上找了很多文章,都不曉得怎麼讓RS在網頁瀏覽時,自動加到它的body,只看到你這些有一點點跟body有關的文章? 感謝你的回覆~~

# by Jeffrey

to LED, 文中介紹的behavior及XBL可以透過CSS在IE及Firefox加掛JavaScript邏輯(雖然手續較繁,也不保證新版本仍會支援),所以只要比照加入類似document.oncontextmenu=function() { return false; }的寫法應該就可以實現跟寫在<body oncontextmenu="...">一樣的效果。不過提醒,這種做法都只能粗淺地防護一般使用者,對於熟悉網頁設計的人來說只有微微增加抓資料的手續而已,不宜對其保護力有過高期待。

Post a comment