Kiedy osadzenie kodu w <script> jest tożsame z wczytaniem go pliku?

0

Jak wiadomo, w HTML można napisać skrypt na dwa sposoby:

<!-- Bezpośrednio -->
<script type="text/javascript">alert("hello world");<script>

<!-- Posrednio, z pliku -->
<script type="text/javascript" src="hello.js"><script>

Przez całe życie byłem przekonany, że to jest dokładnie to samo, nie ma żadnej różnicy, ale właśnie niedawno znalazłem przypadek, w którym to nie jest to samo. Ostatnio bawię się Emscripten i w przypadku programów z Worker i Thread stwierdziłem, że w przypadku wklejenia skryptu do pliku HTML, program przestaje działać. Na forum Emscripten założyłem temat, w którym w ostatniej wiadomości napisałem "jak krowie na rowie", co trzeba zrobić, żeby samemu się o tym przekonać: https://github.com/emscripten-core/emscripten/issues/20567

Przekształcanie na pliki PHP, dopisywanie odpowiednich nagłówków jest po to, żeby przeglądarka miała obiekt SharedArrayBuffer, bez tego, żaden program z wątkami w WASM nie będzie działać. Modyfikacja nie byłaby potrzebna, gdybym dysponował serwerem, który dodaje Cross-Origin-Embedder-Policy: require-corp i Cross-Origin-Opener-Policy: same-origin do każdej odpowiedni na żądanie GET lub POST. Nagłówek Content-Type: text/javascript jest po to, żeby przeglądarka zinterpretowała dany plik jako JavaScript pomimo innego rozszerzenia.

Co w ogóle zmienia wklejenie skryptu do pliku HTML, że coś działa inaczej? Jaki muszą być spełnione warunki, żeby wklejenie skryptu do HTML zupełnie nic, a nic nie zmieniło w interpretacji plików przez przeglądarkę? Jaka jest tak naprawdę różnica pomiędzy JavaScript w HTML a JavaScript w osobnym pliku?

0

Rozumiem, że to jest błąd?

stdthr.php:1041 wasm streaming compile failed: TypeError: Failed to execute 'compile' on 'WebAssembly': Incorrect response MIME type. Expected 'application/wasm'.

Różnica jest taka, że jak kod jest ładowany z pliku to przeglądarka sprawdza czy typ MIME się zgadza. W przypadku JS trzeba dodać jakąś flagę, ale z tego co kojarzę dla WASM to jest zawsze sprawdzane.

Skonfiguruj serwer, żeby zwracał prawidłowy MIME i powinno śmigać.

2
andrzejlisek napisał(a):

Co w ogóle zmienia wklejenie skryptu do pliku HTML, że coś działa inaczej? Jaki muszą być spełnione warunki, żeby wklejenie skryptu do HTML zupełnie nic, a nic nie zmieniło w interpretacji plików przez przeglądarkę?

Przypuszczam, że patrzyłeś w to hasło MDN?

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer

Tam jest o tym, że Spectre było i wyłączyli tę opcję, a potem włączyli na nowo, tylko że musi to być w secure contexts i z nagłówkami.

Chociaż zastanawiam się - czy to znaczy, że jeśli ustawisz nagłówki dla pliku HTML i osadzisz za pomocą tagów script, to będzie działać, czy nie? Czy jednak te nagłówki powinny być ustawiane tylko dla plików *.js?

0

Przed modyfikacją (wstawianie stdthr.js.php do stdthr) pojawiają się w Chrome tylko takie dwa błędy, ale i tak śmiga:

stdthr.php:1041 wasm streaming compile failed: TypeError: Failed to execute 'compile' on 'WebAssembly': Incorrect response MIME type. Expected 'application/wasm'.
stdthr.php:1042 falling back to ArrayBuffer instantiation

A jeżeli zrobię całą czynność z aplikacją, która nie potrzebuje SharedArrayBuffer, to nie potrzebuję wymuszać żadnych nagłówków krzyżowego pochodzenia i śmiga niezależnie od tego, czy pozostawię osobne pliki tak, jak są, czy złożę wszystko do jednego pliku. Nawet, jak wymuszę nagłówki krzyżowego pochodzenia pomimo braku takiej potrzeby, to też śmiga.

Warto byłoby wymusić na serwerze odpowiedni nagłówek MIME dla pliku WASM, ale widzę, że to akurat nie ma znaczenia.

0
LukeJL napisał(a):
andrzejlisek napisał(a):

Co w ogóle zmienia wklejenie skryptu do pliku HTML, że coś działa inaczej? Jaki muszą być spełnione warunki, żeby wklejenie skryptu do HTML zupełnie nic, a nic nie zmieniło w interpretacji plików przez przeglądarkę?

Przypuszczam, że patrzyłeś w to hasło MDN?

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer

Tam jest o tym, że Spectre było i wyłączyli tę opcję, a potem włączyli na nowo, tylko że musi to być w secure contexts i z nagłówkami.

Chociaż zastanawiam się - czy to znaczy, że jeśli ustawisz nagłówki dla pliku HTML i osadzisz za pomocą tagów script, to będzie działać, czy nie? Czy jednak te nagłówki powinny być ustawiane tylko dla plików *.js?

Nie pamiętam, czy akurat w MDN, ale doszukałem się, że żeby wyłączyć SharedArrayBuffer, potrzebne są określone nagłówki, a później poszukałem, jak to zrobić w PHP. Tak naprawdę, to każdy plik HTML/PHP i JS musi mieć te nagłówki. Natomiast jak się włączy ten skrypt: https://github.com/gzuidhof/coi-serviceworker to nagłówki wystarczą w HTML, w JS nie potrzeba, ale bywa problem z działaniem. Po jednym uruchomieniu skryptu poprzez <script src="coi-serviceworker.js"></script> po zrestartowaniu przeglądarki, po logu z działania serwera widzę, że po wywołaniu dowolnego pliki z serwera, po ok. sekundzie woła "coi-serviceworker.js" z serwera. Jeżeli zamiast odniesienia do "coi-serviceworker.js"wkleję kod tego skryptu, to nie zadziała. Nie rozumiem, skąd skrypt "coi-serviceworker.js" wie, jak nazywa się ten plik, skoro nie ma nazwy pliku w treści skryptu.

Sposób ze skryptem "coi-serviceworker.js" bywa zawodny, jak wciskam raz Ft, a raz Ctrl+F5, to zdarza się, że nie działa, nie widzi SharedArrayBuffer, a po restarcie przeglądarki działa. Ten skrypt tak pobieżnie patrząc, ma się podczepić pod jakieś wywołanie przeglądarki, które można skasować poprzez wymazanie ciastek i zawartości offline. Ale skąd skrypt wie, jak on się nazywa? Może jak jest wklejony do HTML, to próbuje się podstawić pusta nazwa i stąd problem?

1

Już wiem, co jest nie tak i skąd bierze się problem.

Chodzi o to, że w Worker jest funkcja importScripts, do której poprzez PostMessage jest podstawiany adres URL skryptu uzyskany za pomocą document.currentScript.src. Jeżeli nie ma osobnego pliku , to automatycznie nie podstawi się ani URL ani blob, dlatego nie zadziała. Można hardkodować URL, ale plik i tak musi istnieć. Teoretycznie, da się wstawić treść pliku i skonwertować na BLOB i to podstawić, będzie działać.

Czyli to nie nagłówki, ani serwer, tylko przekazywanie URL do skryptu JavaScript i importowanie skryptu do Worker jest problemem.

1 użytkowników online, w tym zalogowanych: 0, gości: 1