Networking 如何使用qt5登录web表单

Networking 如何使用qt5登录web表单,networking,web,login,qt5,command-line-interface,Networking,Web,Login,Qt5,Command Line Interface,我所做的是cli multiple IP checker,如果它使用以下方式在线登录到其html表单: 输入类型=文本名称=用户名id=用户名; 输入类型=密码名称=密码id=密码 获取一些属性的值,但是像network.postrequest、loginData或类似的东西,在链接中嵌入用户名和密码是不可行的,我需要一些类似Mechanize的方法,但它只在Ruby和Python中可用。感谢任何帮助,在这几个星期里,我的头撞到了,但没有完成 以下是表格代码: 问题的最新情况: 我编写了包含表单

我所做的是cli multiple IP checker,如果它使用以下方式在线登录到其html表单: 输入类型=文本名称=用户名id=用户名; 输入类型=密码名称=密码id=密码 获取一些属性的值,但是像network.postrequest、loginData或类似的东西,在链接中嵌入用户名和密码是不可行的,我需要一些类似Mechanize的方法,但它只在Ruby和Python中可用。感谢任何帮助,在这几个星期里,我的头撞到了,但没有完成

以下是表格代码:

问题的最新情况:

我编写了包含表单本身和操作文件的小型多部分/表单数据,用于测试以下代码:

一,。表格:

二,。操作文件:

三,。要测试的代码:

这段代码只打印html表单,但应该提交并打印操作结果。它使用.cgi。
有没有办法通过.cgi登录?

可能您没有以正确的形式提供数据。使用工具检查您的程序真正发送到服务器的内容,以及它是否符合您的期望

由于这个问题没有什么其他的话要说,我将继续说明如何使用QNetworkAccessManager正确发送POST请求

更新:这现在适用于多部分表单,而不是普通的URL编码表单。注意,两者不兼容,处理方式完全不同。您可能需要调整.toUtf8以匹配服务器预期的编码

QHttpMultiPart loginData(QHttpMultiPart::FormDataType);
QHttpPart userNamePart;
userNamePart.setHeader(QNetworkRequest::ContentDispositionHeader,
                       QVariant("form-data; name=\"username\""));
userNamePart.setBody(userName.toUtf8());

QHttpPart userPasswordPart;
userPasswordPart.setHeader(QNetworkRequest::ContentDispositionHeader,
                           QVariant("form-data; name=\"password\""));
userPasswordPart.setBody(userPassword.toUtf8());

QHttpPart uriPart;
uriPart.setHeader(QNetworkRequest::ContentDispositionHeader,
                  QVariant("form-data; name=\"uri\""));
uriPart.setBody("/");

loginData.append(userNamePart);
loginData.append(userPasswordPart);
loginData.append(uriPart);

QNetworkRequest loginRequest(loginUrl);

// set up QNetworkAccessManager

QNetworkReply *loginReply = networkManager->post(
            loginRequest,
            &loginData);
// note that the fully encoded representation does contain only ASCII characters

QObject::connect(loginReply, &QNetworkReply::finished, [loginReply]() {
    qDebug() << loginReply->readAll();
});

Connect loginReplys finished signal到处理程序,以检查HTTP状态,并使用(例如)Qt的XML处理工具解析传入数据。在这里,我只是将服务器的回复转储到qDebug。

谢谢您的回复!我使用了你的代码,我得到了httpstatuscode 200,并且没有登录到html部分,如果它可能会帮助表单包含这样的代码:form enctype=multipart/form data id=loginform method=post action=/login.cgi/form是否可以添加完整的表单标记,所有字段,您的问题最好没有标记HTML表单?我更新了我的答案以反映您更新的问题。现在解释多部分表单。由于表单是多部分的,所以一切都变得比正常情况更复杂。请注意,编码可能需要根据服务器的期望进行调整-utf-8应该可以。。。2014年。它解析html时使用200个代码,但不登录。。。你知道怎么解决这个问题吗?当通过usr和pwd时,我是否必须以某种方式按下登录按钮,或者在收到usr和pwd时自动按下登录按钮?检查networkManager->cookieJar->CookieForUrlQurlYourURL的内容。请求完成后,应该有一些会话cookie或类似的东西。此外,通过浏览器登录,在此之前禁用图像、JS等,并使用Wireshark进行捕获。一些网站使用比简单cookie(例如SSO)更复杂的登录方案。检查网络回复的标题。URL必须指向表单的操作URL,而不是表单本身。它适用于无Cookie的表单,但如何使其适用于
<html>   
<head>
 <title>Test Page</title>
</head>   
<body>   
    <h2>Data Collection</h2><p>
    <form enctype="multipart/form-data" id="loginform" method="post" action="proceed.php">  
        <table>
            <tr>
                <td>Name:</td>
                <td><input type="text" name="username" id="username"/></td>
            </tr>   
            <tr>
                <td>Password:</td>
                <td><input type="text" name="password" id="password"/></td>
            </tr>   
            <tr>
                <td colspan="2" align="center">
                <input type="submit"/>
                </td>
            </tr>
        </table>
    </form>
</body>
</html>
<html>
<body>

Welcome <?php echo $_POST["username"]; ?><br>
Your password is: <?php echo $_POST["password"]; ?>

</body>
</html>
void MainWindow::login()
{
manager = new QNetworkAccessManager(this);

//ssl errors ignoring
connect(manager,SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)),
        this,SLOT(onIgnoreSSLErrors(QNetworkReply*,QList<QSslError>)));
theurl = "http://localhost/form/";

QString userName = "usr";
QString userPassword = "pwd";

qDebug() << "Attempting to login with Username =" << userName << "and Password =" << userPassword;
m_userName = userName;

QHttpMultiPart *loginData = new QHttpMultiPart(QHttpMultiPart::FormDataType);
QHttpPart userNamePart;
userNamePart.setHeader(QNetworkRequest::ContentDispositionHeader,
                       QVariant("multipart/form-data; name=\"username\"; filename=\""+ userName + "\""));
userNamePart.setBody(userName.toUtf8());

QHttpPart userPasswordPart;
userPasswordPart.setHeader(QNetworkRequest::ContentDispositionHeader,
                           QVariant("multipart/form-data; name=\"password\"; filename=\""+ userPassword + "\""));
userPasswordPart.setBody(userPassword.toUtf8());

loginData->append(userNamePart);
loginData->append(userPasswordPart);

qDebug() << "OK with code1";

QNetworkRequest request(theurl);
request.setRawHeader( "User-Agent" , "Mozilla Firefox" );

qDebug() << "OK with code2";
QNetworkReply *reply = manager->post(
            request,
            loginData);

loginData->setParent(reply);
qDebug() << "OK with code3";

connect( reply, SIGNAL( finished() ),
         SLOT( _q_onLoginRequestFinished() ) );

connect( reply, SIGNAL( metaDataChanged() ),
         SLOT( _q_onLoginMetaDataChanged() ) );

}

void MainWindow::_q_onLoginRequestFinished()
{
qDebug() << Q_FUNC_INFO;
QNetworkReply* reply = qobject_cast<QNetworkReply*>( sender() );
QByteArray ba = reply->readAll();
qDebug() << ba + " request-finished->";
if ( !reply )
    return;

QList<QNetworkCookie> cookies = qvariant_cast<QList<QNetworkCookie> >(reply->header(QNetworkRequest::SetCookieHeader));
if(cookies.count() != 0){
    //you must tell which cookie goes with which url
    manager->cookieJar()->setCookiesFromUrl(cookies, theurl);
}


qDebug() << QString::number(cookies.count());

if ( ba.isEmpty() )
{
    emit loggedInAs( m_userName );
    m_isLoggedIn = true;
    emit isLoggedInChanged();
}
}

void MainWindow::_q_onLoginMetaDataChanged()
{
qDebug() << Q_FUNC_INFO;

QNetworkReply* reply = qobject_cast<QNetworkReply*>( sender() );
if ( !reply )
    return;

QVariant statusCode = reply->attribute( QNetworkRequest::HttpStatusCodeAttribute );
if ( !statusCode.isValid() )
    return;

int status = statusCode.toInt();

if ( status != 302 )
{
    QString reason = reply->attribute( QNetworkRequest::HttpReasonPhraseAttribute ).toString();
    qDebug() << QString::number(status) + " status num" ;
    qDebug() << tr( "Loging request failed: %1." ).arg( reason );
    emit loginFailed( reason );
}
if(status == 302)
{
    QUrl newUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
    qDebug() << "redirected from xx to " + newUrl.toString();
    QNetworkRequest newRequest(newUrl);
    manager->get(newRequest);
    return;
}

}
QHttpMultiPart loginData(QHttpMultiPart::FormDataType);
QHttpPart userNamePart;
userNamePart.setHeader(QNetworkRequest::ContentDispositionHeader,
                       QVariant("form-data; name=\"username\""));
userNamePart.setBody(userName.toUtf8());

QHttpPart userPasswordPart;
userPasswordPart.setHeader(QNetworkRequest::ContentDispositionHeader,
                           QVariant("form-data; name=\"password\""));
userPasswordPart.setBody(userPassword.toUtf8());

QHttpPart uriPart;
uriPart.setHeader(QNetworkRequest::ContentDispositionHeader,
                  QVariant("form-data; name=\"uri\""));
uriPart.setBody("/");

loginData.append(userNamePart);
loginData.append(userPasswordPart);
loginData.append(uriPart);

QNetworkRequest loginRequest(loginUrl);

// set up QNetworkAccessManager

QNetworkReply *loginReply = networkManager->post(
            loginRequest,
            &loginData);
// note that the fully encoded representation does contain only ASCII characters

QObject::connect(loginReply, &QNetworkReply::finished, [loginReply]() {
    qDebug() << loginReply->readAll();
});