QT進階之路 : QUrl應用

轉載:https://www.2cto.com/kf/201609/547889.html

簡述

QUrl 類提供了一個方便的接口使用 URLs。

它可以解析和構造編碼和未編碼形式的 URLs。QUrl 也支持國際化域名(IDNs)。

詳細描述

最常見的使用QUrl 的方式是通過構造函數來初始化,傳遞一個 QString 參數。


QUrl url("https://github.com/");

然而,也可以使用 setUrl()

QUrl url;

url.setUrl("https://github.com/");

也可以逐漸地構造 URL,通過調用 setScheme()、setUserName()、setPassword()、setHost()、setPort()、setPath()、setQuery() 和 setFragment()。一些方便的函數也可供使用:setAuthority() 設置用戶名、密碼、主機和端口。setUserInfo() 設置用戶名和密碼。

URLs 可以用兩種形式表示:編碼或未編碼。未編碼形式適用於顯示給用戶,編碼形式通常會發送到一個 Web 服務器。例如,未編碼的URL "http://bühler.example.com/List of applicants.xml" 將被髮送到服務器為 "http://xn--bhler-kva.example.com/List%20of%20applicants.xml" 。

可以使用 toString() 來獲取 URL 人類可讀的表示。這種表示方法適合以未編碼形式將 URL 顯示給用戶。然而,編碼的形式由 toEncoded() 返回,僅供內部使用,傳遞給 Web 服務器、郵件客戶等。兩種形式在技術上正確、明確地表示相同的 URL - 事實上,傳遞任何一種形式給 QUrl 的構造函數或使用 setUrl() 都將產生相同的 QUrl 對象。

QUrl 符合 RFC 3986 (統一資源標識符:通用的語法)中的 URL 規範,包括 RFC 1738 (統一資源定位器)中方案的擴展。如果 QUrl 中的摺疊規則符合 RFC 3491 ,它還兼容 file URI specification 來自 freedesktop.org,提供使用 UTF-8(IDN 要求) 本地編碼編碼的文件名。

RFC 3491 是“Nameprep: A Stringprep Profile for Internationalized Domain Names (IDN)”,描述瞭如何準備一個國際化域名,包括對一個域名字段進行映射、正規化以及禁止性過濾等等操作。

錯誤檢查

在 URL 解析或使用單獨的 setter 函數(例如:setScheme()、setHost() 或 setPath())設置 URL 的組成部分時,QUrl 能夠檢測許多錯誤。如果解析或 setter 函數成功,任何先前記錄的錯誤條件將被丟棄。

默認情況下, QUrl 的 setter 函數操作在 QUrl::TolerantMode 解析模式下,這意味著他們接受一些常見錯誤和不實數據。解析的另一種方式是 QUrl::StrictMode,這適用於進一步檢查。詳見 QUrl::ParsingMode 描述不同的解析模式。

QUrl 只檢查符合規範的 URL。它並不試圖驗證被處理程序預期的高層協議的 URLs 格式。例如,下面的 URIs 都被 QUrl 認為是有效,即使在使用時他們不合理:

"http:/filename.html" "mailto://example.com"

當解析器遇到錯誤時,它通過信號事件 isValid() 返回 false,並且 toString() / toEncoded() 返回一個空字符串。如果需要將 URL 未能解析的原因顯示給用戶,可以通過調用 QUrl 的 errorString() 來獲得錯誤條件。

注意:這個信息是高度技術性的,可能對於用戶沒有意義。

QUrl 僅能夠記錄一個錯誤條件。如果找到一個以上錯誤,沒有定義報告哪個錯誤。

字符轉換

遵循這些原則,以避免在處理 URL 和字符串時,出現錯誤的字符轉換:

當從一個 QByteArray 或一個char * 創建包含 URL 的 QString 時,記得要用 QString::fromUtf8()。

URL格式

scheme

scheme 指定使用的傳輸協議,它由 URL 起始部分的一個或多個 ASCII 字符表示。scheme 只能包含 ASCII 字符,對輸入不做轉換或解碼,必須以 ASCII 字母開始。

scheme 嚴格兼容 RFC 3986:scheme = ALPHA *( ALPHA / DIGIT / “+” / “-” / “.” )

協議描述file資源是本地計算機上的文件。格式:file:///,注意後邊應是三個斜槓。ftp通過 FTP 訪問資源。格式:FTP://gopher通過 Gopher 協議訪問該資源。http通過 HTTP 訪問該資源。格式:HTTP://https通過安全的 HTTPS 訪問該資源。格式:HTTPS://mailto資源為電子郵件地址,通過 SMTP 訪問。格式:mailto:MMS通過支持MMS(流媒體)協議的播放該資源(代表軟件:Windows Media Player)。格式:MMS://ed2k通過 支持ed2k(專用下載鏈接)協議的P2P軟件訪問該資源(代表軟件:電驢)。格式:ed2k://Flashget通過 支持Flashget:(專用下載鏈接)協議的P2P軟件訪問該資源(代表軟件:快車)。格式: Flashget://thunder通過 支持thunder(專用下載鏈接)協議的 P2P 軟件訪問該資源(代表軟件:迅雷)。格式: thunder://news通過 NNTP 訪問該資源。

下圖顯示了一個 URL,其 scheme 是 ftp:

QT進階之路 : QUrl應用

<喎�"/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwPtKqyejWwyBzY2hlbWWjrMq508PS1M/Ct73KvaO6PC9jb2RlPjwvY29kZT48L2NvZGU+PC9jb2RlPjwvY29kZT48L3A+DQo8cHJlIGNsYXNzPQ=="brush:java;"> QUrl url; url.setScheme("ftp");

Authority

URL 的 authority 由用戶信息、主機名和端口組成。所有這些元素都是可選的,即使 authority 為空,也是有效的。

格式:username:password@hostname:port

用戶信息和主機由'@' 分割,主機和端口由 ':'分割 。如果用戶信息為空,'@' 必須被省略。儘管端口為空時,允許使用 ':'。

QT進階之路 : QUrl應用

host:指存放資源的服務器的域名系統(DNS)主機名或 IP 地址。

port:整數,可選,省略時使用方案的默認端口,各種傳輸協議都有默認的端口號,如 HTTP 的默認端口為80。如果輸入時省略,則使用默認端口號。有時候出於安全或其他考慮,可以在服務器上對端口進行重定義,即採用非標準端口號,此時,URL 中就不能省略端口號這一項。

user info

user info 指用戶信息,是 URL 中 authority 可選的一部分。

用戶信息包括:用戶名和一個可選的密碼,由 ':' 分割。 如果密碼為空,':'必須被省略。

QT進階之路 : QUrl應用

path

由零或多個 / 隔開的字符串,一般用來表示主機上的一個目錄或文件地址。在 authority 之後,query 之前。

QT進階之路 : QUrl應用

對於沒有層級的 schemes,路徑將是 scheme 後的所有部分,像下面這樣:

QT進階之路 : QUrl應用

query

query 指查詢字符串,可選,用於給動態網頁(例如:使用 CGI、ISAPI、PHP/JSP/ASP/ASP、.NET 等技術製作的網頁)傳遞參數,可有多個參數,用 & 隔開,每個參數的名和值用 = 隔開。

QT進階之路 : QUrl應用

構建一個查詢尤其方便,請參考:Qt之QUrlQuery

fragment

fragment 指定網絡資源中的片斷。是 URL 的最後一部分,由'#' 後面跟的字符串表示。通常指的是用於 HTTP 頁面上的某個鏈接或點。

例如:一個網頁中有多個名詞解釋,可使用 fragment 直接定位到某一名詞解釋。

QT進階之路 : QUrl應用

fragment 有時也被稱為 URL“引用”。

傳遞一個 QString()(null 字符串)將取消 fragment 的設置。傳遞一個參數 QString(“”)(空而非 null 字符串)將 fragment 設置為一個空字符串(和原始 URL 一樣,只有一個 "#")。

深入使用

相對路徑

調用 isRelative() 可以判斷 URL 是否是相對的。一個相對的 URL 可以被轉變通過將它作為參數傳遞給 resolved(),會返回一個絕對 URL。isParentOf() 用來確定一個 URL 是否是另一個的 parent。

QUrl resolved(const QUrl &relative) const

如果 relative 不是一個相對 URL,該函數會直接返回 relative。否則,這兩個 URL 的路徑會進行合併,返回的新 URL 會有 base URL 的 scheme 和 authority。

合併後的路徑,就像下面這樣:

QUrl baseUrl("http://qt.digia.com/Support/");
QUrl relativeUrl("../Product/Library/");
qDebug(baseUrl.resolved(relativeUrl).toString());
// 打印 "http://qt.digia.com/Product/Library/"

調用 resolved() 使用 "..",返回原始目錄的上級目錄。同樣,使用 "../.." 將返回上上一層目錄。如果 relative 是 "/",路徑會變成 "/"。

用戶輸入

[static] QUrl fromUserInput(const QString &userInput)

可以被扣除,返回一個 userInput 指定的有效 URL;如果不能,則會返回一個空 QURL。

大多數應用程序,可以瀏覽網頁,允許用戶輸入一個 URL 形式的簡單字符串。此字符串可以手動輸入到地址欄,從剪貼板中獲得,或者通過命令行參數傳遞。

當沒有一個有效的 URL 字符串時,執行最好的猜測,使各種web相關的假設。

當字符串對應系統上的一個有效文件路徑時,會構造一個 file:// URL,使用 QUrl::fromLocalFile()。

如果不是這種情況,試圖把字符串變成一個 http:// 或 ftp:// URL。這時,後者字符串從以 'ftp' 開始。結果然後通過 QUrl 的 tolerant 解析器傳遞,如果成功,則會返回一個有效的 QUrl;否則,返回 QUrl()。

例如:

qt-project.org -> http://qt-project.org ftp.qt-project.org -> ftp://ftp.qt-project.org hostname -> http://hostname /home/user/test.html -> file:///home/user/test.html

文件名

QString fileName(ComponentFormattingOptions options = FullyDecoded) const

返回文件的名稱,包括目錄路徑。

注意:如果這個 QUrl 對象路徑以斜槓結束,文件的名稱是空的。

如果路徑不包含任何斜線,完全返回作為文件名。

示例:

QUrl url("http://qt-project.org/support/file.html");
// url.adjusted(RemoveFilename) == "http://qt-project.org/support/"
// url.fileName() == "file.html"

參數 options 控制如何格式化文件名稱組成。所有值產生一個明確的結果。使用 QUrl::FullyDecoded,所有百分比編碼序列被解碼;否則,返回值可能包含在QString的編碼形式不能表示的一些百分比編碼序列。

主機、端口

例如,通過 socket 連接到一個指定 QUrl 包含的主機、端口:

QTcpSocket sock;
sock.connectToHost(url.host(), url.port(80));

本地文件

可以使用 fromLocalFile() 構造一個 QUrl,通過傳遞一個本地文件路徑。toLocalFile() 將一個 URL 轉換為本地文件路徑。

QUrl url = QUrl::fromLocalFile("E:\\\\Qt.txt");
// QUrl("file:///E:/Qt.txt")

百分比編碼

為方便生成編碼 URL 字符串或查詢字符串,有兩個靜態函數:fromPercentEncoding() 和 toPercentEncoding(),處理編碼和解碼的百分比 QString 對象。

[static] QByteArray toPercentEncoding(const QString &input, const QByteArray &exclude = QByteArray(), const QByteArray &include = QByteArray())

返回一個編碼的輸入副本 。輸入首先轉換為 UTF-8,沒有在無限制組中的所有 ASCII 字符是百分比編碼的。 為了防止字符變為百分比編碼,可以將他們傳遞給 exclude,為了迫使字符變為百分比編碼,將他們傳遞給 include。

無限制的定義是:ALPHA / DIGIT / “-” / “.” / “_” / “~”

QByteArray ba = QUrl::toPercentEncoding("{a fishy string?}", "{}", "s");
qDebug(ba.constData());

// 打印 "{a fi%73hy %73tring%3F}"

有效性

構建一個 URL 後,可以在任何時候調用 isValid(),來檢查 URL 的有效性。如果返回 false,應該在繼續之前 clear() URL,或通過為 setUrl() 傳遞一個新的 URL 重新開始。

bool isValid() const

URL 運行通過一致性測試。URL 的每一部分都必須符合 URI 標準的標準編碼規則,URL 才是有效的。

bool checkUrl(const QUrl &url) {
if (!url.isValid()) {
qDebug(QString("Invalid URL: %1").arg(url.toString()));
return false;
}

return true;
}


分享到:


相關文章: