Я пытаюсь переписать несколько HTTP-запросов с помощью пользовательской схемы URL:
Все запросы к http://static.foo.bar
должны быть переадресованы на static://...
и обработать некоторый ответ.
Проблема:
Кажется, что перехват и перенаправление работают, но независимо от того, что возвращает моя реализация QWebEngineUrlSchemeHandler
(изображение или html), всегда заменяет полную страницу HTML.
Ожидаемый результат:
Образец изображения /tmp/iphone.jpg
, отправленный с SchemeHandler
, встроен в страницу HTML, поэтому HTML показывает заголовок <h1>
и 2 изображения.
Версии:
Python 3.7.4
PyQt: 5.14.1
Пример кода:
import sys
import signal
from PyQt5 import QtCore
from PyQt5.QtCore import QUrl, QObject
from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEngineSettings, QWebEnginePage, QWebEngineProfile
from PyQt5.QtWebEngineCore import QWebEngineUrlRequestInterceptor, QWebEngineUrlSchemeHandler, QWebEngineUrlScheme
from PyQt5.QtWidgets import QApplication, QMainWindow
class WebEngineUrlRequestInterceptor(QWebEngineUrlRequestInterceptor):
# Everything requested from static.foo.bar goes to static://
# //static.foo.bar/1/2/4.jpeg >> static://1/2/4.jpeg
def interceptRequest(self, info):
print("interceptRequest")
print(info.requestUrl())
if 'static.foo.bar' in str(info.requestUrl()):
url = QUrl()
url.setScheme(MyWebEngineUrlScheme.scheme.decode())
url.setHost('baz.jpg')
print('Intercepting and redirecting to: %s' % url)
info.redirect(url)
class MyWebEnginePage(QWebEnginePage):
# debugging
def acceptNavigationRequest(self, url, _type, isMainFrame):
print("acceptNavigationRequest: %s" % url)
return QWebEnginePage.acceptNavigationRequest(self, url, _type, isMainFrame)
class SchemeHandler(QWebEngineUrlSchemeHandler):
def __init__(self, app):
super().__init__(app)
def requestStarted(self, request):
url = request.requestUrl()
print('SchemeHandler requestStarted: %s' % url)
# Returns a sample image
raw_html = open('/tmp/iphone.jpg', 'rb').read()
buf = QtCore.QBuffer(parent=self)
request.destroyed.connect(buf.deleteLater)
buf.open(QtCore.QIODevice.WriteOnly)
buf.write(raw_html)
buf.seek(0)
buf.close()
request.reply(b"image/jpeg", buf)
return
class MyWebEngineUrlScheme(QObject):
# Register scheme
scheme = b"static"
def __init__(self, parent=None):
super().__init__(parent)
scheme = QWebEngineUrlScheme(MyWebEngineUrlScheme.scheme)
QWebEngineUrlScheme.registerScheme(scheme)
self.m_functions = dict()
def init_handler(self, profile=None):
if profile is None:
profile = QWebEngineProfile.defaultProfile()
handler = profile.urlSchemeHandler(MyWebEngineUrlScheme.scheme)
if handler is not None:
profile.removeUrlSchemeHandler(handler)
self.handler = SchemeHandler(self)
print("registering %s to %s" % (MyWebEngineUrlScheme.scheme, self.handler))
profile.installUrlSchemeHandler(MyWebEngineUrlScheme.scheme, self.handler)
schemeApp = MyWebEngineUrlScheme()
signal.signal(signal.SIGINT, signal.SIG_DFL)
app = QApplication(sys.argv)
win = QMainWindow()
win.resize(800, 600)
html = """
<html>
<body>
<h1>test</h1>
<hr>
<p>First image</p>
<img src="http://static.foo.bar/baz.jpg" />
<hr>
<p>Second image</p>
<img src="https://store.storeimages.cdn-apple.com/4668/as-images.apple.com/is/iphone-xr-red-select-201809?wid=1200&hei=630&fmt=jpeg&qlt=95&op_usm=0.5,0.5&.v=1551226038669" />
</body>
</html>
"""
browser = QWebEngineView()
interceptor = WebEngineUrlRequestInterceptor()
profile = QWebEngineProfile()
profile.setUrlRequestInterceptor(interceptor)
page = MyWebEnginePage(profile, browser)
schemeApp.init_handler(profile)
browser.settings().setAttribute(QWebEngineSettings.PluginsEnabled, True)
browser.settings().setAttribute(QWebEngineSettings.JavascriptCanOpenWindows, False)
browser.settings().setAttribute(QWebEngineSettings.LinksIncludedInFocusChain, False)
browser.settings().setAttribute(QWebEngineSettings.LocalStorageEnabled, True)
browser.settings().setAttribute(QWebEngineSettings.JavascriptEnabled, True)
page.setHtml(html)
browser.setPage(page)
browser.show()
win.setCentralWidget(browser)
win.show()
sys.exit(app.exec_())