[精讚] [會員登入]
334

【Wicket】[nonce]如何導入css以及javascript

如果只是用一般的 HTML link 或是 script 標籤來寫,會被 CSP 擋住,禁止加載資源,那我們除了關閉 CSP 以外還有沒有辦法來解決呢?

分享此文連結 //n.sfs.tw/15705

分享連結 【Wicket】[nonce]如何導入css以及javascript@小編過路君子
(文章歡迎轉載,務必尊重版權註明連結來源)
2022-05-20 16:41:16 最後編修
2022-03-25 08:24:42 By 過路君子
 

哈囉大家好,這裡是找到好方法的小編過路君子

看大家都只說用 CssHeaderItem.forReference() 但是小編一直在想......所以那些人的 CSS 檔案到底放在哪裡?

 

 

如果各位有到 Stackoverflow 之類的網站先去找資料的話,應該不難發現很多人都叫我們這樣寫:

import org.apache.wicket.markup.head.CssHeaderItem;
import org.apache.wicket.request.resource.CssResourceReference;

@Override
public void renderHead(IHeaderResponse response)
{
    response.render(CssHeaderItem.forReference(new CssResourceReference(myCssFile.class, "myCssFile.css")));
}

那現在問題來了,這幾行要寫在哪裡?css 檔案要放在哪裡?需要掛載 css 檔案嗎?

 

先說結論,小編在一陣摸索之後看了以下的訊息:

(所有圖片點擊都可以放大、變高清)

那小編看了以下的輸出至少得知了好像要把 css 打包成 package,但是真的有夠麻煩的

 

所以我們今天不會使用這個方式。

我們直接使用網址的方式,換言之,就是只要寫網址進去就可以了,不用管這個 css 或是 javascript 是同源還是外部的,只要有網址就可以了。

如果真的有需要使用第三方的資源檔,那還是使用小編等等介紹的方式,就算該程式碼帶有惡意,我們最少還是有機會擋下來的。

有關 XSS 的更多資訊可以參考這篇他人的文章:前端防禦從入門到棄坑——CSP變遷@程序猿哪些事

那如果今天我們真的需要從其他網站獲取資訊(例如:溫度、濕度)怎麼辦?也很簡單,就是去設定一下 CSP 的 connect-src 即可,如何設定可以參考這小編這篇文章:【Wicket】[CSP] Content-Security-Policy & Content-Security-Policy-Report-Only@小編過路君子

 

那我們在開始前,照慣例小編一樣先附上目錄結構:

小編會將 css 和 js 放在 webapp 下,而不是 java 下的原因是:

放在 webapp 下走的是 web.xml 的設定,網址就是路徑;但若放在 java 下走的就是 webRoute.java 的設定,網址預設又臭又長,若要漂亮的網址就要掛載,那既然掛載了,不就跟我們直接放在 webapp 一樣?

 

 

如何加載 CSS

因為 CSS 相對起來比較單純,所以我們從這邊開始。

那以我們今天要在 index.html 新增 index.css 為例,假設今天 index.css 內有以下內容:

接著,我們打開 index.java 添加以下的程式碼:

import org.apache.wicket.request.Url;
import org.apache.wicket.request.cycle.RequestCycle;
import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.head.CssReferenceHeaderItem;

public class index extends WebPage
{
    @Override
    public void renderHead(IHeaderResponse response)
    {
        /* 取得目前網頁網址 */
        Url url = RequestCycle.get().getRequest().getUrl();
        String fullUrl = RequestCycle.get().getUrlRenderer().renderFullUrl(url);

        String rootUrl;
        try {rootUrl = fullUrl.substring(0, fullUrl.indexOf('/', fullUrl.indexOf('/')+2));}
        catch(Exception error) {rootUrl = fullUrl;}

        /* 渲染CSS */
        response.render(CssReferenceHeaderItem.forUrl(rootUrl + "/css/index.css"));
    }
}

那其中因為小編都是使用 Wildfly 所以之前網址可能只會打 /css/index.css 這樣,但沒想到在 Apache 上面踢到大鐵板,Apache 的相對連結算法跟 Wildfly 不一樣啊!

所以現在小編不管如何都一定使用網址進行連結,這樣就沒有這個問題了;如果有興趣了解更多可以參考這篇文章:【Wicket】[URI]使用Java取得目前網址@小編過路君子

那這邊有一點要注意的是,我們不用在 HTML 裡面添加 <link href="..." />,Wicket 會自動幫我們產生,所以我們的 HTML 維持原本的樣子即可。

接著刷新頁面。

我們的 CSS 漂亮的出現了!而且還帶有 nonce,所以不會被 CSP 攔下。

 

那如果我們今天要加載的是來自其他網站的 css 呢?那剛好,小編到精讚上隨便抓了一個 css 檔來測試(原檔在這:flags.css)。

一樣的程式碼,如法炮製。

import org.apache.wicket.request.Url;
import org.apache.wicket.request.cycle.RequestCycle;
import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.head.CssReferenceHeaderItem;

public class index extends WebPage
{
    @Override
    public void renderHead(IHeaderResponse response)
    {
        /* 取得目前網頁網址 */
        Url url = RequestCycle.get().getRequest().getUrl();
        String fullUrl = RequestCycle.get().getUrlRenderer().renderFullUrl(url);

        String rootUrl;
        try {rootUrl = fullUrl.substring(0, fullUrl.indexOf('/', fullUrl.indexOf('/')+2));}
        catch(Exception error) {rootUrl = fullUrl;}

        /* 渲染第三方CSS */
        response.render(CssReferenceHeaderItem.forUrl("https://n.sfs.tw/web/css/flags.css"));
    }
}

重新載入網頁並套用對方 css 的屬性。

不要問小編為什麼控制台和網頁原始碼的 HTML 不一樣,因為小編截圖之後才想到要設一個屬性來測試,所以就臨時用 javascript 添加上去。

總之,我們的資源成功載入,屬性也成功套用,完全沒受到半點 CSP 的攔截。

對了,如果對方的 css 內有網址,例如 background: url("..."),那網址的部分照樣會被攔截,所以最好的辦法就是將所有相依資源移到我們本機,因為預設圖片等等是同源 ok 的。

 

 

如何加載 Javascript

如果只是要添加沒有對外互動的 javascript 的話相當單純,絕對不會被 CSP 攔截。

可是一旦發出網頁請求,就會看對方是什麼類型的資源,然後比對該項 CSP,如果是不被允許的,那照樣會直接禁止傳輸。

那我們一樣要在 index.html 裡面加載 index.js 檔案,假設 index.js 內有以下的程式碼:

打開 index.java 添加以下程式碼:

import org.apache.wicket.request.Url;
import org.apache.wicket.request.cycle.RequestCycle;
import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.head.JavaScriptReferenceHeaderItem;

public class index extends WebPage
{
    @Override
    public void renderHead(IHeaderResponse response)
    {
        /* 取得目前網頁網址 */
        Url url = RequestCycle.get().getRequest().getUrl();
        String fullUrl = RequestCycle.get().getUrlRenderer().renderFullUrl(url);
        String rootUrl = fullUrl.substring(0, fullUrl.indexOf('/', fullUrl.indexOf('/')+2));

        /* 渲染javascript */
        response.render(JavaScriptReferenceHeaderItem.forUrl(rootUrl + "/css/index.js"));
    }
}

接著同樣刷新網頁頁面。

跟上面的 CSS 一樣,我們使用網址漂亮的渲染出了 javascript,一樣如果對 Wicket 使用 java 擷取網址有興趣的人這邊請:【Wicket】[URI]使用Java取得目前網址@小編過路君子

小編沒在精讚上面找到比較適合拿來做示範的第三方 javascript,所以示範的部分跳過,但大體邏輯跟 css 一樣:

/* 渲染第三方 javascript */
response.render(JavaScriptReferenceHeaderItem.forUrl("http://uri.here"));

那跟 css 一樣,javascript 如果會像其他的網站發出資源請求,會看請求的資源類型,然後對照相對應的 CSP,若是不符合規則則同樣會禁止存取。

所以如果需要請求其他資源的話,要嘛下載回來放本機,要嘛去修改 CSP 規則,同意下載。

如果是 css 和 javascript 那就算是同源照樣禁止傳輸,最好的辦法是像上面那樣在一開始就渲染好並放到 head 裡,這樣連請求都不用,直接呼叫函式即可。

 

 

 

後記

這樣看起來好像不難對不對,小編也是這麼想。

但是不知道網路上為什麼就是沒有人給出這樣的解法,都只能看到使用 forReference() 的方法,最後小編是跑去 Wicket 9.x API 裡面瞎找,結果還真的讓小編找到了(org.apache.wicket.markup.head.CssHeaderItem)。

沒錯,forUrl() 跟 forReference() 是同一個 class 下的函式,但是卻沒有人提及,想想也是搞笑,因為官方的文檔裡面也是使用 forReference()

END

你可能感興趣的文章

【Maven】用Maven來託管Wildfly/jBoss的部屬(deploy)、解部屬(undeploy) 極簡版,給未來想要抄作業的小編自己,完整的一切設定檔,可以依照個人需求作增刪。

【Discord bot 2.0.1】(discord.ui.View)如何將舊機器人升級至目前最新版本 很多時候升級軟體是為了讓別人覺得你的程式很先進,但這次卻是因為要使用某個新功能

【Firefox \ Maven】[Headless](Linux) 如何使用Maven打包並驅動Firefox 有時候我們需要取得渲染後的網頁,當然是直接呼叫瀏覽器出來用啦

【SeaChest & Synology】512e(Advanced Format / AF) 轉換至 4Kn 好不容易入手了一顆硬碟,但是卻無法使用,除了賣掉還有更好的方法嗎?

【Maven】如何夾帶檔案至Jar內以及其讀取方式 想要讀取一個外部的文字文件?Maven是你的好幫手

【Discord bot】(ERROR)await self.bot.wait_for() 大坑 今天真的是採到大坑,只找到解決方法,具體原因不明

我有話要說

>>

限制:留言最高字數1000字。 限制:未登入訪客,每則留言間隔需超過10分鐘,每日最多5則留言。

訪客留言

[無留言]

隨機好文

[活動] 2017年4/1雲空幻想愚人節活動彩蛋&攻略 (紀念性質) 雲空幻想2017年的愚人節活動介紹同時也是本小編的第一篇網路文章(*^ω^)♪

高捷少女:地下城的探險少女① 婕兒心中一奇,便走上前看著仔細。那塊凹進去的地方中心大約三公分厚,越往邊緣就越淺,圓型直徑十五公分。婕兒拿出銅盤對比一下,發現兩者大小竟然一致,銅盤似乎能夠完整的嵌進去。     婕兒看著凹槽,心中

【歌評】蓮台野夜行 - 幻想的永遠祭 蓮台野的探險雖然結束了,但是,誰知道是不是一段新的探險的序曲呢?

【歌評】過去の花 過去的花 ~ Fairy of Flower 彼岸花(higan bana),就是歌曲名中所指的花,而彼岸花又有「地獄花jigoku bana」的別稱,請注意,蓮台野的周圍可是長滿彼岸花呢!

【日翻中歌詞】LOSER 一如往常的孤身一人 早就已經被折磨殆盡 明明就已經無處可去 卻作著白日夢 晚安 無論何時都是這個樣子 對懵懂夜晚早感到噁心