Search code examples
iwebbrowser2ihtmldocument2

How to set the "base URL" for a HTML document loaded from memory using IWebBrowser2?


I'm using IHTMLDocument2::write() as described here in order to load HTML from memory into an IWebBrowser2 instance. The code is shown below:

#include <MsHTML.h>
void CMyDlg::WriteHTML(const wchar_t* html)
{
    IDispatch* pHtmlDoc = m_explorer.get_Document();
    if (!pHtmlDoc)
        return;
    CComPtr<IHTMLDocument2> doc2;
    doc2.Attach((IHTMLDocument2*)pHtmlDoc);
    if (!doc2)
        return;

    SAFEARRAY* psaStrings = SafeArrayCreateVector(VT_VARIANT, 0, 1);
    if (!psaStrings)
        return;
    BSTR bstr = SysAllocString(html);
    if (bstr)
    {
        VARIANT* param;
        HRESULT hr = SafeArrayAccessData(psaStrings, (LPVOID*)&param);
        if (SUCCEEDED(hr))
        {
            param->vt = VT_BSTR;
            param->bstrVal = bstr;
            hr = SafeArrayUnaccessData(psaStrings);
            if (SUCCEEDED(hr))
            {
                doc2->write(psaStrings);
                doc2->close();
            }
        }
    }
    if (psaStrings)
        SafeArrayDestroy(psaStrings);
}

This works as I'd expect (the HTML is loaded). However none of the linked resources (images etc) can be found because there is no "base URL" from which to load them.

How can I set the base URL for the document such that if there is an image foo.png at "http://bar.com/baz/foo.png", the image can be found via a href of "baz/foo.png" within the loaded document?


Solution

  • If you're running you website off the root, it should work as the default "/".

    (I'm assuming you know where to set base href in the markup, e.g. <base href="/" /> )

    But, if something else is going on, you can start out be setting the base href to the absolute root, e.g. "http://bar.com/"

    Note that using relative roots in the base href was never reliable when I've had to tinker with this; it probably could be, but I figured why bother.

    I used to have to do that for a site when I loaded it down from the root (I'd just copy the bits to a subdirectory of a running webserver and had problems with the images until I just did this). I actually ran it down one more from the root, which is what compelled me to do this, and you're not doing that, which seems to me odd that it doesn't work, but again, it's something to try.

    Later, I did it this way (before started running the app of its own root, allowing me to just use "/"). This allowed me to move it around from test to prod with the same subdirectory root structure:

    <script type="text/javascript">
    document.write("<base href='http://" + document.location.host + "/' />");
    </script>
    

    Both worked for me when I had to do this.