Qt WebView - перехватывать загрузку библиотек JS/CSS для загрузки локальных
Я долго искал документацию, чтобы найти способ сделать это, но пока не увенчался успехом. Основная идея заключается в том, что у меня есть кусок HTML, который я загружаю через веб-просмотр Qt. Одно и то же содержимое можно экспортировать в один HTML-файл.
Этот файл использует библиотеки, такие как Bootstrap и jQuery. В настоящее время я загружаю их через CDN, который работает, когда онлайн просто отлично. Тем не менее, мое приложение также должно работать в автономном режиме. Поэтому я ищу способ перехватить загрузку библиотек в Qt и вместо этого обслуживать локально сохраненный файл. Я пытался установить https QWebEngineUrlSchemeHandler, но это никогда не вызывает метод requestStarted на нем.
(PyQT example follows)
QWebEngineProfile.defaultProfile().installUrlSchemeHandler(b'https', self)
Если я использую другой текст для схемы и внедряю его в страницу, она работает, поэтому я предполагаю, что он не работает, так как Qt уже имеет обработчик по умолчанию, который уже зарегистрирован. Но эта другая схема потерпит неудачу при экспорте файла.
Во всяком случае, вернемся к основному вопросу; Есть ли способ перехватить загрузку библиотек или изменить схему URL, в частности, только в Qt?
Продолжаем с QWebEngineUrlRequestInterceptor, теперь перенаправляя запросы https на мой собственный URI, который имеет обработчик URI. Тем не менее, запрос никогда не доходит до него, потому что: Расположение перенаправления 'conapp://webresource/bootstrap.min.css' имеет запрещенную схему для запросов между источниками. Как мне внести в белый список мою собственную схему conapp uri?
2 ответа
Итак, решение, которое я выбрал в конце, было, во-первых, ввести шаблоны jinja. Затем, используя их, шаблон будет иметь переменные и блоки, установленные на основе экспорта или внутреннего использования, и оттуда мне больше не понадобится перехватчик.
Следующий пример показывает, как я это сделал. Он использует QWebEngineUrlRequestInterceptor для перенаправления содержимого на локальный сервер.
В качестве примера я перехватываю stacks.css для stackru и делаю очевидное изменение.
import requests
import sys
import threading
from PyQt5 import QtWidgets, QtCore
from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEnginePage, QWebEngineProfile
from PyQt5.QtWebEngineCore import QWebEngineUrlRequestInterceptor, QWebEngineUrlRequestInfo
from http.server import HTTPServer, SimpleHTTPRequestHandler
from socketserver import ThreadingMixIn
# Set these to the address you want your local patch server to run
HOST = '127.0.0.1'
PORT = 1235
class WebEngineUrlRequestInterceptor(QWebEngineUrlRequestInterceptor):
def patch_css(self, url):
print('patching', url)
r = requests.get(url)
new_css = r.text + '#mainbar {background-color: cyan;}' # Example of some css change
with open('local_stacks.css', 'w') as outfile:
outfile.write(new_css)
def interceptRequest(self, info: QWebEngineUrlRequestInfo):
url = info.requestUrl().url()
if url == "https://cdn.sstatic.net/Shared/stacks.css?v=596945d5421b":
self.patch_css(url)
print('Using local file for', url)
info.redirect(QtCore.QUrl('http:{}:{}/local_stacks.css'.format(HOST, PORT)))
class ThreadingHTTPServer(ThreadingMixIn, HTTPServer):
"""Threaded HTTPServer"""
app = QtWidgets.QApplication(sys.argv)
# Start up thread to server patched content
server = ThreadingHTTPServer((HOST, PORT), SimpleHTTPRequestHandler)
server_thread = threading.Thread(target=server.serve_forever)
server_thread.daemon = True
server_thread.start()
# Install an interceptor to redirect to patched content
interceptor = WebEngineUrlRequestInterceptor()
profile = QWebEngineProfile.defaultProfile()
profile.setRequestInterceptor(interceptor)
w = QWebEngineView()
w.load(QtCore.QUrl('https://stackru.com'))
w.show()
app.exec_()