Before adding more rewriting to a PHP fetcher, choose where the next resource should go. A document fetched from https://destination.example/catalog/ and returned at https://viewer.example/browse?url=... may contain:

<img src="photo.jpg">
<a href="details/42">Details</a>

The browser resolves those references using the document it received at the viewer. PHP having fetched the original bytes does not establish the remote base.

A base element can point relative URLs at the destination, but those requests may then go directly from browser to destination. Keeping every request through PHP instead requires proxy URLs and a broader routing model:

Resource or actionRequired handling
Links and imagesResolve against the remote document and produce the intended route
CSS imports and resourcesUse the stylesheet's remote base
FormsPreserve method and submitted data
RedirectsKeep navigation inside the allowed model
Script-created requestsHandle URLs absent from the original HTML

A few regular-expression replacements cannot promise general compatibility with script-heavy sites. For a known public document, it may be enough to disable navigation, permit direct links or route a supported subset back through the viewer. Preserve actual media types rather than treating every response as HTML.

Returning untrusted markup from your domain also gives it the viewer's browser origin, not the fetched site's identity. Isolate those documents from account/admin pages. Define per-visitor remote cookies, allowed forwarded headers and redirect destinations; a shared cookie jar can mix remote logins.

Commit to that support boundary before offering a browsing session. For ordinary browsing through another exit, a browser’s native proxy interface, such as Firefox’s HTTP/SOCKS settings, preserves the browser's destination URL and origin model without requiring this fetch-and-republish layer. For a separate public-site test, the free proxy list supplies candidate endpoints; match the protocol in the browser settings.

Related articles