Невозможно локально протестировать страницу веб — сборки с помощью Firefox-SharedArrayBuffer не определен

#firefox #webassembly #httpserver #sharedarraybuffer

Вопрос:

Я использую программное обеспечение на основе веб-сборки, которое использует многопоточность, которая требует SharedArrayBuffer . Он отлично работает как в локальном/развернутом Chromium, так и в развернутом Firefox 89, но поскольку лучшая производительность в Firefox, я хочу протестировать и настроить его на своей машине, поэтому я запускаю python -m SimpleHTTPServer . В этой ситуации, когда я открываю 127.0.0.1:8000 или 0.0.0.0:8000 в Firefox, SharedArrayBuffer не определено. Возможно, это параметр безопасности, но при использовании localhost меня действительно не интересует интерпретация ситуации Firefox-это должно просто выполняться. Как я могу заставить это работать? Нужен ли мне другой веб-сервер, другие настройки?

Комментарии:

1. Возможно, вам не хватает необходимых HTTP-заголовков: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

2. @CherryDT есть идеи, как настроить их с помощью simplehttpserver или с помощью nginx?

3. Я подумал о более простом способе, потому что это звучит так, как будто вы все равно не пропускаете объект postMessage — смотрите мой ответ

Ответ №1:

Как вы правильно догадались, это связано с ограничениями безопасности. Были внесены изменения в отношении использования SharedArrayBuffer , которые уже были реализованы в Firefox 79 и вскоре появятся и в Chrome (начиная с Chrome 92). (Время написания этого: 13 июля 2021 года.)

Основная цель состоит в том, чтобы ограничить использование SharedArrayBuffer s в postMessage . Любая такая попытка приведет к ошибке, если не будут установлены определенные ограничительные заголовки COOP/COEP для предотвращения атак с перекрестным происхождением:

 Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
 

К сожалению, без этих заголовков также не существует глобального SharedArrayBuffer конструктора. По-видимому, это ограничение может быть снято в будущем. Сами объекты все еще работают (только их прохождение postMessage приведет к броску), но вам нужен другой способ их создания. Вы можете использовать WebAssembly.Memory вместо этого:

 const memory = new WebAssembly.Memory({ initial: 10, maximum: 100, shared: true })
// memory.buffer is instanceof SharedMemoryBuffer
 

Теперь вы можете сделать еще один шаг вперед и восстановить конструктор из этого. Поэтому, используя следующий код в качестве «прокладки», ваш существующий код должен работать до тех пор, пока он не попытается передать буфер через postMessage :

 if (typeof SharedArrayBuffer === 'undefined') {
  const dummyMemory = new WebAssembly.Memory({ initial: 0, maximum: 0, shared: true })
  globalThis.SharedArrayBuffer = dummyMemory.buffer.constructor
}

// Now, `new SharedArrayBuffer(1024)` works again
 

Дальнейшее чтение:

Ответ №2:

Как указал @CherryDT в комментарии, проблема заключается в отсутствии заголовков для локального сервера. В интернете есть блог, в котором описан процесс разработки веб-сборки в Firefox с помощью веб-сервера python. Вместо python -m SimpleHTTPServer этого нужно добавить файл ./wasm-server.py с этим содержимым (для Python 2):

 # Python 2

import SimpleHTTPServer
import SocketServer

class WasmHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
    def end_headers(self):        
        self.send_header("Cross-Origin-Opener-Policy", "same-origin")
        self.send_header("Cross-Origin-Embedder-Policy", "require-corp")
        SimpleHTTPServer.SimpleHTTPRequestHandler.end_headers(self)


# Python 3.7.5 adds in the WebAssembly Media Type. Version 2.x doesn't
# have this so add it in.
WasmHandler.extensions_map['.wasm'] = 'application/wasm'


if __name__ == '__main__':
    PORT = 8080
    httpd = SocketServer.TCPServer(("", PORT), WasmHandler)
    print("Listening on port {}. Press Ctrl C to stop.".format(PORT))
    httpd.serve_forever()
 

затем можно протестировать приложение по адресу 127.0.0.1:8080