2

Так что я создаю приложение Chrome со встроенным элементом <webview>. Встроенный webapp содержит много устаревших кодов, таких как window.showModalDialog звонки (которые Chrome больше не поддерживает).Polyfill window.showModalDialog в webview

То, что я пытаюсь сделать сейчас, - это заполнить эти звонки. Я создал простой тестовый пример:

<webview src="http://legacyCodeIsAwesome.com/" style="width:100%; height:100%"></webview> 

код работает на WebView элемента:

webview.addEventListener('contentload', function() { 
    webview.executeScript(
     { 
     code: 'window.showModalDialog = function() { console.log ("Hello, world");}', 
     runAt: 'document_start' 
     } 
    ); 
    }); 

Вышеприведенные код работает (добавление отладки console.log работы), только он не делает то, что это предположительно, чтобы перезаписать функцию showModalDialog.

Есть ли какие-то ограничения на функции перезаписи на объекте window в веб-просмотрах? Есть ли способ обойти это?

ответ

1

Когда вы звоните webview.executeScript, вы по существу создаете Content Script.

Одним из основных принципов сценариев контента является isolated world: сценарий содержимого видит отдельную копию объекта window.

Скрипты содержания выполняются в специальной среде, называемой изолированным миром. Они имеют доступ к DOM страницы, на которую они вставляются, но не на любые переменные или функции JavaScript, созданные на этой странице. Он выглядит для каждого сценария контента так, как если бы на его запущенной странице не было другого исполняемого кода JavaScript. То же самое верно в обратном: JavaScript, запущенный на странице, не может вызывать какие-либо функции или обращаться к любым переменным, определенным сценариями контента.

Итак, ваше переопределение работает, но только в контексте контекста содержимого.

Чтобы выполнить переопределение в самом контексте страницы, , нам нужно углубиться в. We need to go deeper

Сценарий контента может создавать на странице элемент <script>; код в указанном элементе будет выполняться в контексте страницы. Вы можете прочитать об этом методе, называемом сценарием на уровне страницы или вложенными скриптами, in this canonical question.

// Content script 
var script = document.createElement('script'); 
script.textContent = ` 
    window.showModalDialog = function() { 
    console.log("Hello, world"); 
    } 
`; 
(document.head||document.documentElement).appendChild(script); 
script.remove(); 

Тем не менее, вы инъекционного код слишком поздно. На contentload злоумышленник JS, скорее всего, уже выполнен, и добавление "document_start" не собирается перематывать время.

К счастью, вы можете declare in advance the content scripts you want to have:

webview.addContentScripts([ 
    { 
    name: "showModalDialogPolyfill", 
    matches: ["https://webapp.example.com/*"], 
    js: { files: ['content.js'] }, 
    run_at: 'document_start' 
    } 
]); 
webview.src = "https://webapp.example.com/"; 
+0

Спасибо большое за ваш обширный ответ, я хочу дать вам +2 для справки вводного –

+0

Просто небольшой коррекции, но 'matches' должна быть массив –

+0

@NexusDuck Исправлено, спасибо. – Xan