原文: JavaFx WebView使用研究 | Stars-One的雜貨小窩
本篇是基於TornadoFx框架的基礎研究的,示例程式碼都是Kotlin版本,各位可以看著參考下
WebView中比較重要的是其內建的engine物件,後續的相關操作都是通過這個物件進行管理
載入網頁
使用WebView
內建的engine
物件的load()
方法進行網頁的載入
class TestView : View("My View") {
var webView by singleAssign<WebView>()
override val root = vbox {
setPrefSize(600.0,500.0)
webView = webview {
}
webView.engine.load("https://stars-one.site")
}
}
獲取頁面地址
獲取當前頁面地址直接獲取location屬性值即可
val currentUrl = engine.location
上述是直接獲取頁面地址,除此之外,engine還提供了一個頁面地址變化的監聽器,如下程式碼:
engine.locationProperty().addListener { observable, oldValue, newValue ->
println("之前的網址: ${oldValue}")
println("新載入網址: ${newValue}")
}
獲取頁面內容
val htmlStr = webView.engine.document.ownerDocument.textContent
也可以設定個監聽器,每次頁面發生跳轉的時候,會觸發監聽的回撥,來獲取新的頁面內容資料,程式碼如下:
engine.documentProperty().addListener { observable, oldValue, newValue ->
//頁面Document
val htmlStr = oldValue.ownerDocument.textContent
//這裡如果Html是有動態載入iframe,是沒法拿到iframe載入的資料內容的,即使你再網頁上已經看到載入完畢了!!
}
PS:需要注意的是,如果html中的使用js去動態載入iframe的內容,使用上述方法並不能獲取iframe內載入的文件內容
cookie的讀寫
WebView中,有個cookie處理器,預設是 com.sun.webkit.network.CookieManager
,這個我們可以拿到cookie的字串,但是沒法去設定cookie
研究的時候全網找了下方法,算是曲線救國解決了(也不知道合不合理,具體就沒過多研究了)
在webview載入網址url之前,我們得先使用CookieManager.setDefault()
方法去設定一個我們定義好的物件CookieManager(java.net包中)
之後,想要獲取Cookie即可呼叫CookieHandler.getDefault()
方法獲取
獲取cookie
val cookieManager = CookieHandler.getDefault() as CookieManager
val cookieStore = cookieManager.cookieStore
val map = mutableMapOf<URI, List<HttpCookie>>()
//根據域名去找域名下的cookie
cookieStore.urIs.forEach {
//如果想要獲取指定域名,建議在這裡加個判斷條件,過濾一下域名
val httpCookieList = cookieStore[it]
map[it] = httpCookieList
}
關於cookie儲存和設定
fun saveCookie() {
val cookieManager = CookieHandler.getDefault() as CookieManager
val cookieStore = cookieManager.cookieStore
val map = mutableMapOf<URI, List<HttpCookie>>()
cookieStore.urIs.forEach {
val httpCookieList = cookieStore[it]
map[it] = httpCookieList
}
val localCookie = LocalCookie(map)
//將實體類的資料轉為json字串進行儲存
val cookieManagerStr = Gson().toJson(localCookie)
//下面是用了tornadofx內建的儲存,將字串寫入了指定的配置檔案中,可以替換成實現的步驟
//之後首次進來需要讀取該檔案,將cookie設定即可
config["cookieManagerStr"] = cookieManagerStr
config.save()
}
//實體類
data class LocalCookie(val map: Map<URI, List<HttpCookie>>)
進來時候cookie的設定:
fun loadCookie() {
//1.讀檔案將json字串讀取
val buffer = StringBuffer()
val json = config.string("cookieManagerStr", "")
//2.建立一個CookieManager(這裡要匯入java.net包中)
val myCookie = CookieManager()
if (json.isNotBlank()) {
//3. 迴圈將資料重新寫入到CookieManager中
val localCookie = Gson().fromJson(json, LocalCookie::class.java)
localCookie.map.forEach { key, list ->
list.forEach {
//注意:這裡是判斷cookie是否過期,過期就不新增到裡面了
if (!it.hasExpired()) {
myCookie.cookieStore.add(key, it)
}
}
}
}
//4.設定cookie(如果沒有cookie的話,這樣設定也沒事)
CookieManager.setDefault(myCookie)
}
cookie的妙用:
某些網站中某些頁面需要登入才能訪問的的,其實本質上就是在訪問網頁前新增了cookie的引數
我們可以先使用webview訪問其網頁,讓使用者掃碼進行登入,之後獲取cookie的數值,拼接成字串,然後訪問那些需要才能訪問的網頁
訪問網頁的時候請求頭的header中帶上cookie
屬性(具體設定可參照你使用的網路框架),之後即可繞過登入的限制