<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # 【Qt編程】基于Qt的詞典開發系列--用戶登錄及API調用的實現 在上一篇文章《[調用網絡API](http://blog.csdn.net/tengweitw/article/details/45484803)》中,我只講述了如何直觀的使用API接口以及調用API后返回的結果,本文則從程序實現的角度來實現API的調用,當然本程序的實現也是借助于扇貝網的API接口文檔[http://www.shanbay.com/help/developer/api/](http://www.shanbay.com/help/developer/api/)。 由[API文檔](http://www.shanbay.com/help/developer/api/)可知,要想調用其API,必須先注冊。因此,我就注冊了,賬戶名為nineheadedbird, 密碼為123456。顯然,我們要查詞,首先必須得登錄該賬戶。如果用瀏覽器,那就很簡單,只需單純的輸入用戶名和密碼就可以了。可實際上,這一操作并不簡單,只是瀏覽器為我們做了這一切。如果我們要通過程序來實現上述功能的話,就需要用到Qt中的get()函數了,而發送請求的內容格式就至關重要了。 ##查看請求格式 **我們可以通過瀏覽器來查看請求格式**:首先用谷歌瀏覽器(其他瀏覽器也可以,不過你要百度一下怎么來查看這些格式)打開扇貝網的登錄界面[http://www.shanbay.com/accounts/login/](http://www.shanbay.com/accounts/login/)?,在谷歌瀏覽器的設置中單擊開發者選項,然后刷新一下頁眉,就會出現如下的界面:? ![](https://box.kancloud.cn/2016-01-15_5698c1c803347.jpg) 然后**點擊右邊的第一個文件login**,就會出現下面的內容:? ![](https://box.kancloud.cn/2016-01-15_5698c1c823cc8.jpg) 從上圖可以看出,**內容分為三類**:**General、Response Headers、Request Headers**? 在**General**中可以看到**Request Method為GET**(一般還有另一種方式POST,這在Qt中都有對應的函數),Status Code為200表示正常。在Response Headers 中**我們關注的是Set-Cookie中的csrftoken的值**,因為這在我們登錄時需要這個值。**我們最關心的是Request Headers的內容,這部分就是我們請求函數中內容格式**!參考上述的具體內容如下:? ![](https://box.kancloud.cn/2016-01-15_5698c1c84763b.jpg) **我們的程序可以寫成如下的方式:** ~~~ QNetworkRequest request; request.setUrl(QUrl("http://www.shanbay.com/accounts/login/")); request.setRawHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"); request.setRawHeader("Accept-Language","zh-CN,zh;q=0.8"); request.setRawHeader("Cache-Control","max-age=0"); request.setRawHeader("Connection","keep-alive"); request.setRawHeader("Host","www.shanbay.com"); request.setRawHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.63 Safari/535.7"); http->get(request); ~~~ 當我們執行上述的請求之后,服務器就會作答,作答的內容就是上面的Response Headers,而我們需要的是Set-Cookie中的csrftoken的值。**在Qt中,我們將程序中finished信號與我們定義的槽關聯,即每當網絡應答結束時,都會發射這個信號,從而觸發該槽函數的執行,來處理服務器的應答內容**。在程序中,getCookie函數就是來獲取csrftoken的值。 ## 用戶登錄 獲得csrftoken的值后,我們就需要實現登錄操作了。除了上述的請求格式之外,我們還需要加入csrftoken的值、用戶名以及密碼。**具體格式可見下述代碼:** ~~~ QNetworkRequest request; request.setUrl(QUrl("http://www.shanbay.com/accounts/login/")); request.setRawHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"); request.setRawHeader("Accept-Language","zh-CN,zh;q=0.8"); request.setRawHeader("Cache-Control","max-age=0"); request.setRawHeader("Connection","keep-alive"); request.setRawHeader("Host","www.shanbay.com"); request.setRawHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.63 Safari/535.7"); request.setRawHeader("Origin","http//www.shanbay.com"); request.setRawHeader("Referer","http://www.shanbay.com/accounts/login/"); request.setRawHeader("Host","www.shanbay.com"); request.setRawHeader("Content-Type","application/x-www-form-urlencoded"); QByteArray postData; postData.append(QString("csrfmiddlewaretoken=%1&").arg(sessionid));//csrftoken的值 postData.append(QString("username=%1&password=%2&").arg(QUrl::toPercentEncoding(username).constData()).arg(password));//用戶名及密碼 postData.append("login=登錄&continue=home&u=1&next="); request.setHeader(QNetworkRequest::ContentLengthHeader,postData.size()); httpAction=LoginAction; http->post(request,postData); ~~~ ##調用API 完成登錄之后,就可以進行查詞和添詞操作了。除了上述提到的請求頭格式之外,只需要遵守API規范(《[調用網絡API](http://blog.csdn.net/tengweitw/article/details/45484803)》中提到請求格式)即可。**查詞及添詞的程序實現分別如下:** ~~~ void netWork::queryWord(const QString &word)//查詞操作 { QNetworkRequest request; request.setUrl(QUrl("http://www.shanbay.com/api/word/"+word)); request.setRawHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"); request.setRawHeader("Accept-Charset","GBK,utf-8;q=0.7,*;q=0.3"); request.setRawHeader("Accept-Language","zh-CN,zh;q=0.8"); request.setRawHeader("Cache-Control","max-age=0"); request.setRawHeader("Connection","keep-alive"); request.setRawHeader("Host","www.shanbay.com"); request.setRawHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.63 Safari/535.7"); httpAction=QueryWordAction; http->get(request); } void netWork::addWord(const QString &word)//添詞操作 { if(word.isEmpty()) qDebug()<<"你的輸入有誤"; else { QNetworkRequest request; request.setUrl(QUrl("http://www.shanbay.com/api/learning/add/"+word)); request.setRawHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"); request.setRawHeader("Accept-Charset","GBK,utf-8;q=0.7,*;q=0.3"); request.setRawHeader("Accept-Language","zh-CN,zh;q=0.8"); request.setRawHeader("Cache-Control","max-age=0"); request.setRawHeader("Connection","keep-alive"); request.setRawHeader("Host","www.shanbay.com"); request.setRawHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.63 Safari/535.7"); httpAction=AddWordAction; http->get(request); } } ~~~ ## 完整流程 至此,API調用的各個功能已經實現,**下面給出程序的整體思路**:**首先**獲取csrftoken的值(每次都不同);**然后**利用用戶名、密碼及csrftoken的值來登錄;**接著**就可以調用API了。在程序中,每當進行請求,都會在replyfinished函數中用case語句來分別處理這些請求對應的應答。**注意**,不要連續的進行請求,否則可能發生沖突。在程序中,為了防止沖突,我在connectNet請求后,在其應答處理函數中再進行loginShanbay的登錄,然后在其應答函數中進行queryWord查詞請求,然后在其對應的應答處理函數中進行addWord添詞請求。**其結果顯示如下:** ![](https://box.kancloud.cn/2016-01-15_5698c1c85d338.jpg) ## 程序實現 **下面我們給出具體的程序實現(qt 5版本,使用到網絡類,需要加上QT += network)**:首先建立一個空的qt子項目,然后添加一個名為netWork的類,繼承自QObject,然后再添加一個名為main的源文件,這三個文件的內容分別如下:? **1、network.h文件** ~~~ #ifndef NETWORK_H #define NETWORK_H #include <QObject> #include <QtNetwork/QNetworkAccessManager> #include<QtNetwork/QNetworkReply> #include<QtNetwork/QNetworkRequest> #include<QtNetwork/QNetworkCookie> #include<QtNetwork/QNetworkCookieJar> #include <QJsonDocument> #include <QJsonObject> #include <QJsonArray> #include <QJsonValue> #include<QString> #include<QDebug> #include<QList> #include<QUrl> #include<QByteArray> class netWork : public QObject //由于程序文件直接摘自整個項目文件,所以程序中有關的定義或函數沒有使用,但是這個程序可以單獨運行 { Q_OBJECT public: explicit netWork(QObject *parent = 0); // ~netWork(); enum HttpAction{NoAction,NetStudy,GetSessionidAction,LoginAction,QueryWordAction,AddWordAction,AddExampleAction,QueryWordExamplesAction}; HttpAction httpAction; QNetworkAccessManager * http; QString sessionid; QString queryword;//要查詢的單詞 QString nickname; QString username; QString password; bool isBusy; QString getCookie(const QString &name); void loginShanbay(); void queryWord(const QString &word); void queryExamples(QString learningid); void connectNet(QString username="nineheadedbird", QString password="123456"); void addWord(const QString &word); signals://這里的信號都沒有用到 void connectSuccess(); void connectFail(); void verifySuccess(); void verifyFail(); void NetState(bool); public slots: void replyfinished(QNetworkReply*); }; #endif // NETWORK_H ~~~ **2、network.cpp文件** ~~~ #include "network.h" #include<QList> #include<QDesktopServices> netWork::netWork(QObject *parent) : QObject(parent) { http=new QNetworkAccessManager(this); http->setCookieJar(new QNetworkCookieJar(this)); connect(http,SIGNAL(finished(QNetworkReply*)),this,SLOT(replyfinished(QNetworkReply*)));//將finished信號與我們定義的槽關聯,每當網絡應答結束時,都會發射這個信號 isBusy=true; } QString netWork::getCookie(const QString &name)//用于獲得SessionId { foreach(QNetworkCookie cookie , http->cookieJar()->cookiesForUrl(QUrl("http://www.shanbay.com/"))) { if(cookie.name()==name) { qDebug()<<"csrftoken:"<<cookie.value(); return cookie.value(); } } return ""; } void netWork::connectNet(QString username, QString password)//連接網絡,使用默認的用戶名和密碼 { this->username=username; this->password=password; QNetworkRequest request; request.setUrl(QUrl("http://www.shanbay.com/accounts/login/")); request.setRawHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"); request.setRawHeader("Accept-Language","zh-CN,zh;q=0.8"); request.setRawHeader("Cache-Control","max-age=0"); request.setRawHeader("Connection","keep-alive"); request.setRawHeader("Host","www.shanbay.com"); request.setRawHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.63 Safari/535.7"); httpAction=GetSessionidAction; http->get(request); } void netWork::replyfinished(QNetworkReply *reply)//每當執行網站應答結束后,就會執行該槽函數 { QVariant status_code=reply->attribute(QNetworkRequest::HttpStatusCodeAttribute); qDebug()<<"code_state="<<status_code;//網絡狀態,200代表正常,302代表重定向,404:not found等等 if(status_code==QVariant::Invalid)//判斷是否連接到網站,即當前設備能否上網 emit NetState(false); else emit NetState(true); switch(httpAction)//根據我們都進行了什么網絡請求 { case NoAction: break; case GetSessionidAction://獲取SessionId sessionid=getCookie("csrftoken"); if(!sessionid.isEmpty()) { emit connectSuccess(); qDebug()<<("已經連接扇貝網,正在驗證用戶名密碼..."); loginShanbay(); }else { emit connectFail(); qDebug()<<("Cannot connect to the website!"); } break; case LoginAction: //進行登錄操作 httpAction=NoAction; if(0==reply->readAll().size()) { QString nickname=QUrl::fromPercentEncoding(getCookie("username").toLatin1()); emit verifySuccess(); qDebug()<<"Successfully Login"<<nickname; queryWord("hello"); }else { emit verifyFail(); qDebug()<<"Failed to login!"; } break; case QueryWordAction://查詞操作 qDebug()<<"----query word----"; qDebug()<<reply->readAll();//讀取查詞結果 addWord("hello");//添加單詞到單詞本 break; case AddWordAction://添詞操作 qDebug()<<"---add word----"; qDebug()<<reply->readAll();//返回添加詞語的learning_id break; default:break; } } void netWork::loginShanbay()//賬戶密碼的登錄操作 { QNetworkRequest request; request.setUrl(QUrl("http://www.shanbay.com/accounts/login/")); request.setRawHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"); request.setRawHeader("Accept-Language","zh-CN,zh;q=0.8"); request.setRawHeader("Cache-Control","max-age=0"); request.setRawHeader("Connection","keep-alive"); request.setRawHeader("Host","www.shanbay.com"); request.setRawHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.63 Safari/535.7"); request.setRawHeader("Origin","http//www.shanbay.com"); request.setRawHeader("Referer","http://www.shanbay.com/accounts/login/"); request.setRawHeader("Host","www.shanbay.com"); request.setRawHeader("Content-Type","application/x-www-form-urlencoded"); QByteArray postData; postData.append(QString("csrfmiddlewaretoken=%1&").arg(sessionid)); postData.append(QString("username=%1&password=%2&").arg(QUrl::toPercentEncoding(username).constData()).arg(password)); postData.append("login=登錄&continue=home&u=1&next="); request.setHeader(QNetworkRequest::ContentLengthHeader,postData.size()); httpAction=LoginAction; http->post(request,postData); } void netWork::queryWord(const QString &word)//查詞操作 { QNetworkRequest request; request.setUrl(QUrl("http://www.shanbay.com/api/word/"+word)); request.setRawHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"); request.setRawHeader("Accept-Charset","GBK,utf-8;q=0.7,*;q=0.3"); request.setRawHeader("Accept-Language","zh-CN,zh;q=0.8"); request.setRawHeader("Cache-Control","max-age=0"); request.setRawHeader("Connection","keep-alive"); request.setRawHeader("Host","www.shanbay.com"); request.setRawHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.63 Safari/535.7"); httpAction=QueryWordAction; http->get(request); } void netWork::addWord(const QString &word)//添詞操作 { if(word.isEmpty()) qDebug()<<"你的輸入有誤"; else { QNetworkRequest request; request.setUrl(QUrl("http://www.shanbay.com/api/learning/add/"+word)); request.setRawHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"); request.setRawHeader("Accept-Charset","GBK,utf-8;q=0.7,*;q=0.3"); request.setRawHeader("Accept-Language","zh-CN,zh;q=0.8"); request.setRawHeader("Cache-Control","max-age=0"); request.setRawHeader("Connection","keep-alive"); request.setRawHeader("Host","www.shanbay.com"); request.setRawHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.63 Safari/535.7"); httpAction=AddWordAction; http->get(request); } } ~~~ **3、main.cpp文件** ~~~ #include <QApplication> #include "network.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); netWork *nW = new netWork(); // nW->connectNet(); // nW->loginShanbay(); // nW->queryWord("hello"); return a.exec(); } ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看