【问题标题】:How to tell QML XMLHttpRequest to either ignore or use self-signed certificate如何告诉 QML XMLHttpRequest 忽略或使用自签名证书
【发布时间】:2022-01-03 05:23:12
【问题描述】:

(这是一个特定于 QML 的问题) 我想使用 XMLHttpRequest 从 QML 客户端在同一台机器上访问 https://localhost:5000 的 REST 服务器。

如果使用浏览器访问,则在单击有关无效证书(它是自签名证书)的警告后,服务器可以工作。但是从 QML 中,XMLHttpRequest 总是失败,没有响应并且状态==0。

注意:我控制着我的本地机器并且知道端口 5000 上正在监听什么(它是盈透证券的独立 API 网关 REST 服务器)。我可以将此服务器配置为使用我自己的自签名证书,但不能改变太多。服务器不支持http,只支持https。

那么在这种情况下,我该如何做相当于接受浏览器发出的警告,但使用 QML?

或者,我如何告诉 QML 信任我的自签名证书?

我正在使用 Qt/qml 6.2.1

import QtQuick
Rectangle {
  Component.onCompleted: {
    let xhr = new XMLHttpRequest();
    xhr.onerror = function() { console.log(`*****onerror called`); }
    xhr.onreadystatechange = function() {
      console.log(`*****onreadystatechange readyState=${xhr.readyState}`);
      if (xhr.readyState == 4) {
        console.log(`==== RESPONSE =====`);
        console.log(`status:${xhr.status}`);
        console.log(`responseURL:${xhr.responseURL}`);
        console.log(`responseText:${xhr.responseText}`);
        console.log(`getAllResponseHeaders():${xhr.getAllResponseHeaders()}`);
        console.log(`===(end)===`);
        Qt.quit();
      }
    };
    //let url = "https://qt.io";  // this works
    let url = "https://localhost:5000/v1/api/sso/validate";
    console.log(`url:${url}`);
    xhr.open("GET", url, false);
    xhr.responseType = "json";
    xhr.setRequestHeader('Content-type', 'application/json');
    xhr.send();

  }
}

上面运行时的输出是qml:

qml: url:https://localhost:5000/v1/api/sso/validate
qml: *****onreadystatechange readyState=1
qml: *****onreadystatechange readyState=4
qml: ==== RESPONSE =====
qml: status:0
qml: responseURL:undefined
qml: responseText:
qml: getAllResponseHeaders():
qml: ===(end)===
qml: *****onerror called

顺便说一句,QML 代码可以与其他具有普通证书的 url 一起正常工作。

【问题讨论】:

    标签: qt xmlhttprequest qml


    【解决方案1】:

    据我所知,Qt 中没有解决方案。我在一个项目中通过继承QQmlWebsocket并覆盖setSocket函数解决了这个问题。

    void MyWebSocket::setSocket(QWebSocket *socket)
    {
        connect(socket, &QWebSocket::sslErrors, [socket](const QList<QSslError> &errors){
            if(errors.length() == 1 && errors[0].error() == QSslError::SelfSignedCertificate)  {
                socket->ignoreSslErrors();
            }
        });
        QQmlWebSocket::setSocket(socket);
    }
    

    这个 MyWebsocket 类应该被导出到 Qml 并用来代替 QMLWebsocket。

    【讨论】:

      猜你喜欢
      • 2018-07-18
      • 1970-01-01
      • 1970-01-01
      • 2016-07-27
      • 2012-08-30
      • 2011-01-16
      • 2018-07-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多