我有一个用 Qt 编写的客户端应用程序,它在 Web 浏览器中与 WebAssembly 一起运行。现在我想将服务器 URL 作为环境变量传递给应用程序(我不想为客户端连接到的每个不同服务器重新编译应用程序)。
我的目标是通过类似的方式访问 qt 应用程序 http://server1.myclient.io 一些 javascript 设置环境变量 SERVER_URL=wss://server1.foo.org
这允许我连接到具有相同二进制但不同子域的不同服务器。
如果目的只是获取服务器地址,则可以在 Qt 应用程序的 C++ 代码中访问它。
#include <emscripten/val.h>
...
emscripten::val location = emscripten::val::global("location");
auto host = location["hostname"].as<std::string>();
auto port = location["port"].as<std::string>();
这基本上可以让你访问 JavaScript window.location 对象。
@Karmo 的回答对我帮助很大。然而,我发现
window.location.href
才是我真正需要的:
#ifdef EMSCRIPTEN
#include <emscripten/val.h>
#include <emscripten.h>
#endif
// ...
QUrl App::href() const {
#ifdef EMSCRIPTEN
emscripten::val location = emscripten::val::global("location");
return QUrl(QString::fromStdString(location["href"].as<std::string>()));
#else
return QUrl();
#endif
}
不知道这是否仍然与您相关,但我一直在寻找完全相同问题的解决方案,并在官方 Qt 论坛中找到了这个帖子:
https://forum.qt.io/topic/112228/qt-webasssembly-pass-url-parameter-to-qml/4
有一个尚未集成的更改就是这样做的:
https://codereview.qt-project.org/c/qt/qtbase/+/248624
它是对 qtloader.js 的一个小改动,所以你甚至不需要重新编译。因为大部分工作已经在 Emscripten 中进行。您可以以正常方式访问参数 QCoreApplication::arguments()
所以像这样的网址: http://192.168.1.106:6931/wasm-args.html?arguments=yes&argument2=no
将收到这样的参数: ("./this.program", "arguments=yes", "argument2=no")*
对于我自己来说,我仍在寻找一种优雅的解决方案来不显示地址中的参数
扩展其他答案,这里是一个以相对自然的方式将参数传递给 Qt wasm 应用程序的解决方案:
https://host.web/WasmApplication.html?arguments=argument1+argument2+argument3
。此代码片段位于 main
的开头,将修改 argc/argv,以便其下游的任何内容都具有额外的 URL 派生参数。
#ifdef Q_OS_WASM
#include <emscripten.h>
#include <emscripten/val.h>
#include <QUrl>
#include <QUrlQuery>
#endif
...
#ifdef Q_OS_WASM
emscripten::val location = emscripten::val::global("location");
QUrlQuery query(QUrl(QString::fromStdString(
location["href"].as<std::string>())));
// Proxy argv, the storage and pointers respectively
std::vector<QByteArray> arguments;
std::vector<char*> argvProxy;
if(query.hasQueryItem(u"arguments"_s))
{
// Copy existing arguments
for(int i = 0; i < argc; i++)
argvProxy.push_back(argv[i]);
const auto queryItems = query.queryItemValue(u"arguments"_s,
QUrl::FullyEncoded).split('+');
for(const auto& queryItem : queryItems)
{
arguments.emplace_back(QUrl::fromPercentEncoding(
queryItem.toUtf8()).toUtf8());
argvProxy.push_back(arguments.back().data());
argc++;
}
argv = argvProxy.data();
}
#endif