因爲我沒有看到chrome添加了一些特定的頭文件(或者無論如何通知服務器prerendering狀態)可能無法在服務器端檢測到它...至少不是直接。但是,您可以模擬客戶端的檢測,然後將其與服務器調用結合使用。
注意,您可以在客戶端檢測預渲染:
if (document.webkitVisibilityState == 'prerender' || document.visibilityState == 'prerender' || document.visibilityState[0] == 'prerender') {
// prerendering takes place
}
現在,你可以打破在客戶端處於預壓狀態下預加載通過顯示的情況下,瀏覽器的警告框(或你大概可以做同樣的在JavaScript中只是一些錯誤,而不是使用警報,()):
if (document.webkitVisibilityState == 'prerender' || document.visibilityState == 'prerender' || document.visibilityState[0] == 'prerender') {
alert('this is alert during prerendering..')
}
現在,當鉻預呈現它會失敗,因爲JavaScript警告將阻止瀏覽器繼續執行JavaScript的網頁。
如果您輸入chrome:chrome:// net-internals /#prerender您可以跟蹤chrome何時執行預渲染以及哪些頁面執行預渲染。在上面的例子中的情況下(與預渲染期間警告框),你可以看到有:
的link rel預渲染(跨 域)http://some.url.which.is.preloaded的Javascript 警報 2015年6月7日19:26:18.758
最終狀態 - Javascript Alret證明chrome未能預加載頁面(我測試過了)。
現在如何解決您的問題?那麼,你可以結合這與異步調用(AJAX)並加載一些內容(來自另一個網址),取決於頁面實際上是否預渲染。
考慮下面的代碼(這可能是由您portlet下面的網址/測試的portlet被渲染):
<html>
<body>
<div id="content"></div>
<script>
if (document.webkitVisibilityState == 'prerender' || document.visibilityState == 'prerender' || document.visibilityState[0] == 'prerender') {
// when chrome uses prerendering we block the request with alert
alert('this is alert during prerendering..');
} else {
// in case no prerendering takes place we load the actual content asynchronously
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
// when the content is loaded we place the html inside "content" div
document.getElementById('content').innerHTML = xhr.responseText;
}
}
xhr.open('GET', '/hidden-portlet', true); // we call the actual portlet
xhr.send(null);
}
</script>
</body>
</html>
正如你所看到的/隱藏的portlet只加載的情況下,瀏覽器加載頁面正常(沒有預加載)。 url/hidden-portlet(可以是另一個portlet/servlet)下的服務器端處理程序包含在預渲染期間不應執行的實際代碼。因此,它是/隱藏的portlet,其執行
dummyRepository.changeSomeData(request.getAttribute("userId"));
此portlet還可以返回普通視圖(渲染HTML)將被異步置於頁面上的URL /測試的portlet感謝下的把戲/測試 - portlet:document.getElementById('content').innerHTML = xhr.responseText;
。
因此,在地址/ test-portlet下sumarize portlet只會返回帶有JavaScript代碼的HTML,這會觸發實際的portlet。
如果你有很多脆弱的portlet,你可以更進一步,所以你可以通過請求參數/test-portlet?actualUrl=hidden-portlet
來參數化你/ test-portlet,這樣實際portlet的地址就可以從url中讀取請求參數在服務器端)。服務器會在這種情況下,動態呈現其應加載的網址:
因此,而不是硬編碼:
xhr.open('GET', '/hidden-portlet', true);
,你將有
xhr.open('GET', '/THIS_IS_DYNAMICALLY_REPLACED_EITHER_ON_SERVER_OR_CLIENT_SIDE_WITH_THE_ADDRES_FROM_URL', true);
你檢查請求的頭部?有沒有任何表示您處於「預加載」場景的標題?在這種情況下,您可以跳過您需要跳過的任何內容。 – geert3
可以ü簡要描述你的數據庫程序是什麼? –
@MSIbrahim我剛剛簡化了場景。實際上有一個REST API調用可以處理2個數據庫。我不認爲這是相關的,因爲我確實不想在較低的層次上進行更改,因爲它嚴格地說是web層的問題。 – Reins