问题
I am using TWebBrowser in DesignMode (Doc.DesignMode := 'On') to compose a HTML document. There is no document (HTML file on disk) loaded in TWebBrowser. I create the document from zero directly in TWebBrowser. The html code will be extracted from TWebBrowser and saved as c:/MyProjects/SomeHtmlName.html.
The problem is that it won't show images I insert if they have relative path.
More exactly, if I paste this code in the WebBrowser it will instantly display the image:
<IMG src="file:///c:/MyProjects/resources/R.PNG">
However, if I enter:
<IMG border=0 src="resources\R.PNG">
<IMG border=0 src="resources/R.PNG"> <---- preferred so it will work on Linux
it will display an image placeholder instead of the actual image.
I need relative paths so the web site will still work if I change the root path OR if I upload it on FTP.
procedure TForm1.Button1Click(Sender: TObject);
begin
LoadDummyPage;
SetHtmlCode('<img src="resources/test_img.PNG">');
Memo1.Text:= GetHtmlCode;
end;
function TForm1.LoadDummyPage: Boolean;
const FileName: string= 'c:\MyProject\_ONLINE WEB SITE\dummy.html';
begin
if not Assigned(wbBrowser.Document)
then wbBrowser.Navigate('about:blank');
Result := FileExists(FileName);
if Result
then wbBrowser.Navigate('file://' + FileName)
else Caption:= 'file not found';
end;
procedure TForm1.SetHtmlCode(const HTMLCode: string);
var
Doc: Variant;
begin
if not Assigned(wbBrowser.Document)
then wbBrowser.Navigate('about:blank');
Doc := wbBrowser.Document;
Doc.Write(HTMLCode);
Doc.Close;
Doc.DesignMode := 'On';
WHILE wbBrowser.ReadyState < READYSTATE_INTERACTIVE
DO Application.ProcessMessages;
Doc.body.style.fontFamily := 'Arial';
Doc.Close;
end;
function TForm1.GetHtmlCode: string; { Get the HTML code from the browser }
var
Doc: IHTMLDocument2;
BodyElement: IHTMLElement;
begin
if Assigned(wbBrowser.Document) and (wbBrowser.Document.QueryInterface(IHTMLDocument2, Doc) = S_OK) then
begin
BodyElement := Doc.body;
if Assigned(BodyElement) then
Result := BodyElement.innerHTML;
end;
if Result > ''
then Result := StringReplace(Result, '="about:', '="', [rfReplaceAll, rfIgnoreCase]); { Fix the 'How stop TWebBrowser from adding 'file:///' in front of my links' bug }
end;
回答1:
You need to pre-load a valid HTML "template" string/stream including the BASE
tag where you set the desired path (with trailing slash) e.g. "file:///c:/MyProjects/"
.
And switch to edit mode, where your images SRC
should be relative e.g. "resources/R.PNG"
. Your final extracted HTML ater editing should be the body.innerHTML
or body.outerHTML
(whatever you need). You can even take the whole document source (google it).
Wrap the extracted source with valid HTML/Body WITHOUT the BASE
tag and save to disk at c:\MyProjects
.
but the code resulted for IMG SRC is full path!
Nothing much you can do about it. this is how the DOM represent the HTML - it's not necessary the HTML source code. this behavior is not consistent. and also depend on how you insert images (I do not use execCommand
and have my own dialog and insert my own html code). You need to manually replace the extracted source "file:///c:/MyProjects/"
with empty string. at least, this is how I do it.
Edit: You don't need to Navigate()
to an external file. you can write the "template"/"empty" HTML via document.write(HTML)
.
Try this:
const
HTML_TEMPLATE = '<html><head><base href="file:///%s"></head><body style="font-family:Arial">%s</body></html>';
procedure TForm1.LoadHTML(HTMLCode: string);
var
Doc: Variant;
HTML, Path: string;
begin
Path := 'D:\Temp\';
HTML := Format(HTML_TEMPLATE, [Path, HTMLCode]);
WebBrowser1.Navigate('about:blank');
Doc := WebBrowser1.Document;
Doc.Write(HTML);
Doc.Close;
Doc.DesignMode := 'On';
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
LoadHTML('<b>Hello</b><img SRC="resources/1.png">');
end;
procedure TForm1.Button2Click(Sender: TObject);
var
Doc: IHTMLDocument2;
begin
Doc := WebBrowser1.Document as IHTMLDocument2;
if Assigned(Doc) then
begin
ShowMessage(Doc.body.innerHTML);
end;
end;
The output for me is: <B>Hello</B><IMG src="resources/1.png">
. in some cases the src
might contain the full path. I can't 100% be sure to when this happens. but you need to be ready to deal with this situation by manually replacing the path. there is no conclusive documentation about this so I always deal with this issue in any case.
回答2:
I suggest to use a small embedded web server such as Internet Direct (Indy) TIdHttpServer, which is able to serve all HTTP requests in a standard way. This removes all potential file system trouble.
来源:https://stackoverflow.com/questions/42003101/how-to-show-relative-path-images-in-twebbrowser