Reputation: 315
I am sending a request to a website manually, and rendering the response's body in a WebView
. For this, I've used the WebView
's engine's loadContent
method:
String bodyOfResponse = ...;
myWebView.getEngine().loadContent(bodyOfResponse);
The problem with this, is that the WebView
gets its content off a String
, not a location, so it has no idea how to resolve relative links in HTML of the content I give it:
<span onclick="document.location.href='/'">Home</span>
The WebView
can't find what that '/'
refers to, since I didn't give the WebView
content via a URL. Is there a way that I can set the current document's location (or baseURI, I've heard it called) so that my WebView
will know how to resolve relative paths? (I know the original server's URL.)
I've seen that using an absolute location in the content, rather than a relative one, is enough to get the WebView
to load the data at the location, but I can't modify the server and have it serve me absolute URLs in all HTML pages.
It would be splendid if I could just webEngine.setBasePath(serverURL)
... but I can't. :(
Upvotes: 1
Views: 381
Reputation: 44345
Wait for the WebEngine’s Document to finish loading, then add a <base> element inside <head>
:
String newBaseURL = "http://www.example.com/app";
myWebView.getEngine().getLoadWorker().stateProperty().addListener(
(obs, old, state) -> {
if (state == Worker.State.SUCCEEDED) {
Document doc = myWebView.getEngine().getDocument();
XPath xpath = XPathFactory.newInstance().newXPath();
try {
Element base = (Element) xpath.evaluate(
"//*[local-name()='head']/*[local-name()='base']",
doc, XPathConstants.NODE);
if (base == null) {
Element head = (Element) xpath.evaluate(
"//*[local-name()='head']",
doc, XPathConstants.NODE);
if (head == null) {
head = doc.createElement("head");
Element html = (Element) xpath.evaluate(
"//*[local-name()='html']",
doc, XPathConstants.NODE);
html.insertBefore(head, html.getFirstChild());
}
base = doc.createElement("base");
head.insertBefore(base, head.getFirstChild());
}
base.setAttribute("href", newBaseURL);
} catch (XPathException e) {
e.printStackTrace();
}
}
});
myWebView.getEngine().loadContent(bodyOfResponse);
Upvotes: 2