有没有办法在没有JavaScript的情况下获得对DOM和/或WebAPI(即全屏API)的读/写访问权限?
我正在尝试用C构建一个基本的应用程序(C源实际上是从GC语言转换的结果).我正在构建的应用程序将作为桌面应用程序运行(它不打算在"真正的"浏览器中运行)所以我可以根据需要调整环境(即布局引擎).
我正在尝试使用webAssembly并尝试找出一种验证webAssembly模块使用的JS方法的完整性的方法.
出于讨论的目的,让我们假设二进制模块不是hackable(我知道情况并非如此),但JS方面是.
给出以下C代码:
#include <emscripten.h>
//js method to validate
void validateMe();
int validateMethods(){
// check validateMe integrity.
// return 1 if validation succeeded.
}
EMSCRIPTEN_KEEPALIVE
void doStuff(){
if (validateMethods()){
// do stuff
}
}
Run Code Online (Sandbox Code Playgroud)
我想doStuff()从JS方面打电话,doStuff()只有在完整性检查成功后才会运行.我想做一些完整性检查,类似于Subresource,检查方法的toString表示.但是,如果我想获得当前(内存中)JS方法toString,我将不得不调用可能被泄露的JS.
问:我可以以某种方式以不同的方式获取toString吗?任何其他方法也将不胜感激.
更新:深入挖掘后,阅读本文,似乎没有办法访问共享数组以外的JS内存.因此,任何验证技术将不胜感激.
更新2(目标):我的最终目标是确保WASM部分仅适用于特定的JS,或者至少使得与操纵的JS交互更加困难.
小提琴实施例:将下列小提琴,是一种幼稚功能验证,通过炭比较功能炭的的toString.如果更改validateMe函数,则验证失败.我试图"防弹"它.
因此,我正在探索将 WebAssembly 存储在 JavaScript 文件中的概念,以便将其全部捆绑在一个可交付文件中。我确实设法制作了一个工作示例,它将 wasm 文件存储在 base64 的大文字字符串中,并在运行时转换为 Uint8Array,然后再处理为模块和实例。
await Deno.writeTextFile(
'./static/wasm/bundle.js',
`import { initSync } from './app.js'\ninitSync(new WebAssembly.Module(Uint8Array.from(atob('${btoa(
[ ...await Deno.readFile('./static/wasm/app_bg.wasm') ]
.map(byte => String.fromCharCode(byte))
.join('')
)}').split('').map(char => char.charCodeAt(0)))))`
)
Run Code Online (Sandbox Code Playgroud)
但我一直想知道,在 wasm 文件非常大的情况下,JavaScript 在处理这个文字字符串时是否可能会出现问题。在此代码片段中,base64 文字字符串在开始时只需要一次,我想它会被垃圾收集器处理掉,因为它不再可访问。
我想知道人们是否对如何存储这种相同类型的数据有任何想法,这些数据硬编码在 JavaScript 中,它只运行一次,但不会在运行时开始时导致任何巨大的内存峰值。增加处理时间以减少峰值内存使用量是一个可以接受的权衡,但获取任何外部资源会破坏问题的重点。
如何File在WebAssembly内存上下文中传递要读取的内容?
使用JavaScript在浏览器中读取文件很简单:
<input class="file-selector" type="file" id="files" name="files[]" />
Run Code Online (Sandbox Code Playgroud)
我能够使用crate stdweb来引导用Rust编写的WebAssembly代码,向DOM元素添加一个事件监听器并启动FileReader:
let reader = FileReader::new();
let file_input_element: InputElement = document().query_selector(".file-selector").unwrap().unwrap().try_into().unwrap();
file_input_element.add_event_listener(enclose!( (reader, file_input_element) move |event: InputEvent| {
// mystery part
}));
Run Code Online (Sandbox Code Playgroud)
在JavaScript中,我会从元素中获取文件并将其传递给阅读器,但是,stdweb的API需要以下签名:
pub fn read_as_array_buffer<T: IBlob>(&self, blob: &T) -> Result<(), TODO>
Run Code Online (Sandbox Code Playgroud)
我不知道如何实现IBlob,我确信我遗漏了一些明显的东西,无论是使用stdweb API还是我对WebAssembly/Rust的理解.我希望有一些东西比将东西转换为UTF-8更简洁.
我在我试过的所有浏览器中偶然发现了一些奇怪的行为:
当我尝试通过实例化WebAssembly.Memory对象来为WebAssembly分配内存时,例如:
new WebAssembly.Memory({ initial: 1 })
Run Code Online (Sandbox Code Playgroud)
在Chrome/Chromium中,我得到:
VM274:1 Uncaught RangeError: WebAssembly.Memory(): could not allocate memory
at <anonymous>:1:1
(anonymous) @ VM274:1
Run Code Online (Sandbox Code Playgroud)
在Firefox中,我得到:
Error: out of memory
Run Code Online (Sandbox Code Playgroud)
Node.js中的分配工作正常,但出于某种原因,我的所有浏览器都失败了.我不知道该怎么做,所有依赖WebAssembly的网站都因此无法使用.
我怀疑Linux正在阻止浏览器(但不是node.js?)分配内存,但这只是一个疯狂的猜测.另一台计算机上几乎相同的安装工作正常,但在这台特定的机器上,浏览器的每次分配都会失败.
有谁知道发生了什么?
这是我的输出ulimit -a:
-t: cpu time (seconds) unlimited
-f: file size (blocks) unlimited
-d: data seg size (kbytes) unlimited
-s: stack size (kbytes) 8192
-c: core file size (blocks) unlimited
-m: resident set size (kbytes) unlimited
-u: processes 31215
-n: file …Run Code Online (Sandbox Code Playgroud) 我目前正在使用 Emscripten 将我们的 C++ 代码编译成 Wasm。通过这样做,我输出了两个文件 *.js 和 *.wasm。后来我使用我们的实现在上面写了更多的 Javascript 代码,这导致我们得到 3 个文件:
index.js
wasmFile.js
wasmFile.wasm
Run Code Online (Sandbox Code Playgroud)
我正在尝试使用 webpack 创建一个文件,该文件将在构建时而不是运行时使用这段代码打包所有内容:
function loadScript(url = "wasmFile.js") {
var script = document.createElement( "script" );
script.src = url;
document.getElementsByTagName( "head" )[0].appendChild( script );
await new Promise<void>((res) => {
Module.onRuntimeInitialized = () => res();
});
}
Run Code Online (Sandbox Code Playgroud)
我已经查看了https://github.com/ballercat/wasm-loader但是,看起来我需要为我的所有函数创建一个 WebAssembly.Instance - 并且 Wasm 文件有很多函数来创建一个实例每个。
这就是我们的 WebPack 配置目前的样子:
module.exports = {
entry: './src/index.ts',
module: {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/
},
{
test: …Run Code Online (Sandbox Code Playgroud) 我有一个 Blazor WASM PWA 应用程序,已在 IIS 上的托管服务上发布。我遇到的问题是有时应用程序不会在访问者的浏览器中更新。即他们看到的是旧版本的应用程序。
我知道应用程序缓存应该由 Service Worker 更新,因此您可能需要访问该网站一次,然后关闭浏览器并再次访问它才能获取更新的版本。然而,有时看起来缓存只是被搞乱了,无论如何,应用程序都不会更新。我找到的唯一解决方案是按 F12,转到“应用程序”选项卡并删除其中的所有内容 -> 这将强制再次下载应用程序的最新版本。
有谁知道发生了什么事以及我该如何解决这个问题?
我从这个Rust代码创建了一个小的WASM文件:
#[no_mangle]
pub fn hello() -> &'static str {
"hello from rust"
}
Run Code Online (Sandbox Code Playgroud)
它构建并且hello可以从JS调用该函数:
<!DOCTYPE html>
<html>
<body>
<script>
fetch('main.wasm')
.then(response => response.arrayBuffer())
.then(bytes => WebAssembly.instantiate(bytes, {}))
.then(results => {
alert(results.instance.exports.hello());
});
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
我的问题是alert显示"未定义".如果我返回a i32,它可以工作并显示i32.我也尝试返回String但是它不起作用(它仍然显示"未定义").
有没有办法从WebAssembly中的Rust返回一个字符串?我应该使用什么类型的?
我有一个chrome扩展,包括一个复杂的功能comp_func(data),通过执行许多按位操作需要大量的CPU.因此,我正在尝试使用WebAssembly.
第一个链接说:
fetch('simple.wasm').then(response =>
response.arrayBuffer()
).then(bytes =>
WebAssembly.instantiate(bytes, importObject)
).then(results => {
results.instance.exports.exported_func();
});
Run Code Online (Sandbox Code Playgroud)
但是我收到一个错误:
未捕获(承诺)TypeError:WebAssembly实例化:导入#0 module ="env"错误:模块不是对象或函数
我已经尝试了很多使用这种方法,但它没有用.我无法理解如何使用从.wasm文件加载的WebAssembly .
所以我尝试了一种更简单的方法:第二个链接说将该行放在html文件中:
<script src="index.js"></script>
Run Code Online (Sandbox Code Playgroud)
然后只使用导出的函数:
var result = _roll_dice();
Run Code Online (Sandbox Code Playgroud)
但是,我正在扩展所以我只有一个background.html文件.所以我正在寻找一种方法来访问后台文件中加载的模块.事情变得复杂,因为函数comp_func(data)是从Worker调用的.
这是我到目前为止所尝试的:
如果我打电话,chrome.extension.getBackgroundPage()我可以访问模块,但我无法将其发送给工人:
无法在'Worker'上执行'postMessage':#无法克隆.
如果我先尝试一下stringify:
未捕获的TypeError:将循环结构转换为JSON
(我试图解开它,没有用......)
我无法chrome.extension.getBackgroundPage()从工作人员打电话,因为我无法从那里访问chrome API.
所以我的问题是:
.wasmchrome扩展文件并且它有效吗?第二种方法(加载js文件)听起来更简单,但如果你有一个这种方法的工作示例,它将是伟大的.或2.如何访问已加载的模块background.html(从第二个示例)?
或者3.如何将我需要的函数从js文件传递给Worker(via postMessage)?
总结一下,有人试图在chrome扩展中使用WebAssembly并幸存下来吗?
编辑:我最终离开了WebAssembly的方法.我也在bugs-chromium发布了这个问题,几个月后得到了答案.不确定这是否真的有效,但也许这一点,以及明确的答案,将有助于某人.
我正在尝试在WebAssembly中提交一个简单的HTTP GET请求.为此,我编写了这个程序(从Emscripten网站复制,稍作修改):
#include <stdio.h>
#include <string.h>
#ifdef __EMSCRIPTEN__
#include <emscripten/fetch.h>
#include <emscripten.h>
#endif
void downloadSucceeded(emscripten_fetch_t *fetch) {
printf("Finished downloading %llu bytes from URL %s.\n", fetch->numBytes, fetch->url);
// The data is now available at fetch->data[0] through fetch->data[fetch->numBytes-1];
emscripten_fetch_close(fetch); // Free data associated with the fetch.
}
void downloadFailed(emscripten_fetch_t *fetch) {
printf("Downloading %s failed, HTTP failure status code: %d.\n", fetch->url, fetch->status);
emscripten_fetch_close(fetch); // Also free data on failure.
}
unsigned int EMSCRIPTEN_KEEPALIVE GetRequest() {
emscripten_fetch_attr_t attr;
emscripten_fetch_attr_init(&attr);
strcpy(attr.requestMethod, "GET");
attr.attributes …Run Code Online (Sandbox Code Playgroud) webassembly ×10
javascript ×6
emscripten ×3
c ×2
rust ×2
asp.net-core ×1
blazor ×1
browser ×1
deno ×1
http ×1
linux ×1
memory ×1
security ×1
web-worker ×1
webidl ×1
webpack ×1