原文: 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
屬性(具體設置可參照你使用的網絡框架),之后即可繞過登錄的限制