问题描述
我使用用户输入的URL作为文本来初始化QUrl对象.稍后,我想将QUrl转换回字符串以显示它,并使用正则表达式进行检查.只要用户不输入任何百分比编码的URL,此方法就可以正常工作.
I use a URL entered by the user as text to initialize a QUrl object. Later I want to convert the QUrl back into a string for displaying it and to check it using regular expression. This works fine as long as the user does not enter any percent encoded URLs.
以下示例代码为什么不起作用?
Why doesn't the following example code work?
qDebug() << QUrl("http://test.com/query?q=%2B%2Be%3Axyz%2Fen").toDisplayString(QUrl::FullyDecoded);
它根本不会解码任何百分比编码的字符.它应该打印"http://test.com/query?q=++e:xyz/en"
,但实际上会打印"http://test.com/query?q=%2B%2Be%3Axyz%2Fen"
.
It simply doesn't decode any of the percent-encoded characters. It should print "http://test.com/query?q=++e:xyz/en"
but it actually prints "http://test.com/query?q=%2B%2Be%3Axyz%2Fen"
.
我也尝试了许多其他方法,例如fromUserInput(),但是我无法使代码在Qt5.3中正常工作.
I also tried a lot of other methods like fromUserInput() but I could not make the code work correctly in Qt5.3.
有人可以向我解释如何执行此操作,以及为什么即使使用QUrl :: FullyDecoded时,上述代码也不起作用(即显示解码的URL)?
Can someone explain me how to do this and why the above code doesn't work (i.e. showing the decoded URL) even when using QUrl::FullyDecoded?
更新
在获得fromPercentEncoding()提示后,我尝试了以下代码:
After getting the fromPercentEncoding() hint, I tried the following code:
QUrl UrlFromUserInput(const QString& input)
{
QByteArray latin = input.toLatin1();
QByteArray utf8 = input.toUtf8();
if (latin != utf8)
{
// URL string containing unicode characters (no percent encoding expected)
return QUrl::fromUserInput(input);
}
else
{
// URL string containing ASCII characters only (assume possible %-encoding)
return QUrl::fromUserInput(QUrl::fromPercentEncoding(input.toLatin1()));
}
}
这允许用户输入unicode URL和百分比编码的URL,并且可以对两种URL进行解码以进行显示/匹配.但是,百分比编码的URL在QWebView中不起作用... Web服务器的响应不同(它返回了不同的页面).显然,QUrl :: fromPercentEncoding()并不是一个干净的解决方案,因为它可以有效地更改URL.我可以在上面的函数中创建两个QUrl对象...一个直接构造,一个使用fromPercentEncoding()构造,第一个用于QWebView,第二个仅用于显示/匹配...,但这似乎很荒谬.
This allows the user to input unicode URLs and percent-encoded URLs and it is possible to decode both kinds of URLs for displaying/matching. However the percent-encoded URLs did not work in QWebView... the web-server responded differently (it returned a different page). So obviously QUrl::fromPercentEncoding() is not a clean solution since it effectively changes the URL. I could create two QUrl objects in the above function... one constructed directly, one constructed using fromPercentEncoding(), using the first for QWebView and the latter for displaying/matching only... but this seems absurd.
推荐答案
结论
我已经做过一些研究,到目前为止的结论是:荒谬.
QUrl::fromPercentEncoding()
是解决之道,OP在 UPDATE 部分中所做的事情应该是标题问题的公认答案.
QUrl::fromPercentEncoding()
is the way to go and what OP has done in the UPDATE section should've been the accepted answer to the question in title.
我认为Qt的文档 QUrl::toDisplayString
有点误导:
I think Qt's document of QUrl::toDisplayString
is a little bit misleading :
实际上,它不具有任何解码功能,此处的文档尚不清楚其行为.但是至少密码部分是正确的.我在 出色的:
Actually it doesn't claim any decoding ability, the document here is unclear about it's behavior. But at least the password part is true. I've found some clues on Gitorious:
测试代码
为了辨别不同功能的解码能力.以下代码已在 Qt 5.2.1 上进行了测试(尚未在Qt 5.3上进行过测试!)
Test Code
In order to discern the decoding ability of different functions. The following code has been tested on Qt 5.2.1 (not tested on Qt 5.3 yet!)
QString target(/*path*/);
QUrl url_path(target);
qDebug() << "[Original String]:" << target;
qDebug() << "--------------------------------------------------------------------";
qDebug() << "(QUrl::toEncoded) :" << url_path.toEncoded(QUrl::FullyEncoded);
qDebug() << "(QUrl::url) :" << url_path.url();
qDebug() << "(QUrl::toString) :" << url_path.toString();
qDebug() << "(QUrl::toDisplayString) :" << url_path.toDisplayString(QUrl::FullyDecoded);
qDebug() << "(QUrl::fromPercentEncoding):" << url_path.fromPercentEncoding(target.toUtf8());
- 返回QByteArray:
QUrl::toEncoded
- 返回QString:
QUrl::url
,QUrl::toString
,,QUrl::fromPercentEncoding
- Return QByteArray:
QUrl::toEncoded
- Return QString:
QUrl::url
,QUrl::toString
,QUrl::toDisplayString
,QUrl::fromPercentEncoding
P.S. QUrl::url
只是QUrl::toString
的同义词.
P.S. QUrl::url
is just synonym for QUrl::toString
.
[案例1]::目标路径= "%_%"
(测试编码功能):
[Case 1]: When target path = "%_%"
(test the functionality of encoding):
[Original String]: "%_%"
--------------------------------------------------------------------
(QUrl::toEncoded) : "%25_%25"
(QUrl::url) : "%25_%25"
(QUrl::toString) : "%25_%25"
(QUrl::toDisplayString) : "%25_%25"
(QUrl::fromPercentEncoding): "%_%"
[案例2]::目标路径= "Meow !"
(测试编码功能):
[Case 2]: When target path = "Meow !"
(test the functionality of encoding):
[Original String]: "Meow !"
--------------------------------------------------------------------
(QUrl::toEncoded) : "Meow%20!"
(QUrl::url) : "Meow !"
(QUrl::toString) : "Meow !"
(QUrl::toDisplayString) : "Meow%20!" // "Meow !" when using QUrl::PrettyDecoded mode
(QUrl::fromPercentEncoding): "Meow !"
[案例3]::目标路径= "Meow|!"
(测试编码的功能):
[Case 3]: When target path = "Meow|!"
(test the functionality of encoding):
[Original String]: "Meow|!"
--------------------------------------------------------------------
(QUrl::toEncoded) : "Meow%7C!"
(QUrl::url) : "Meow%7C!"
(QUrl::toString) : "Meow%7C!"
(QUrl::toDisplayString) : "Meow|!" // "Meow%7C!" when using QUrl::PrettyDecoded mode
(QUrl::fromPercentEncoding): "Meow|!"
[情况4]::目标路径= "http://test.com/query?q=++e:xyz/en"
(未编码%)时:
[Case 4]: When target path = "http://test.com/query?q=++e:xyz/en"
(none % encoded):
[Original String]: "http://test.com/query?q=++e:xyz/en"
--------------------------------------------------------------------
(QUrl::toEncoded) : "http://test.com/query?q=++e:xyz/en"
(QUrl::url) : "http://test.com/query?q=++e:xyz/en"
(QUrl::toString) : "http://test.com/query?q=++e:xyz/en"
(QUrl::toDisplayString) : "http://test.com/query?q=++e:xyz/en"
(QUrl::fromPercentEncoding): "http://test.com/query?q=++e:xyz/en"
[情况5]::目标路径= "http://test.com/query?q=%2B%2Be%3Axyz%2Fen"
(%编码)时:
[Case 5]: When target path = "http://test.com/query?q=%2B%2Be%3Axyz%2Fen"
(% encoded):
[Original String]: "http://test.com/query?q=%2B%2Be%3Axyz%2Fen"
--------------------------------------------------------------------
(QUrl::toEncoded) : "http://test.com/query?q=%2B%2Be%3Axyz%2Fen"
(QUrl::url) : "http://test.com/query?q=%2B%2Be%3Axyz%2Fen"
(QUrl::toString) : "http://test.com/query?q=%2B%2Be%3Axyz%2Fen"
(QUrl::toDisplayString) : "http://test.com/query?q=%2B%2Be%3Axyz%2Fen"
(QUrl::fromPercentEncoding): "http://test.com/query?q=++e:xyz/en"
P.S.我还遇到了Ilya在评论中提到的错误:百分比编码在QUrl中似乎不适用于"+"
P.S. I also encounter the bug that Ilya mentioned in comments: Percent Encoding doesn't seem to be working for '+' in QUrl
QUrl::toDisplayString
的结果是不明确的.如文档所述,必须谨慎使用 QUrl::FullyDecoded
模式.无论您使用哪种类型的URL,都必须用QUrl::toEncode
进行编码,并在必要时用QUrl::fromPercentEncoding
显示它们.
The result of QUrl::toDisplayString
is ambiguous. As the document says, the QUrl::FullyDecoded
mode must be used with care. No matter what type of URL you got, encode them by QUrl::toEncode
and display them with QUrl::fromPercentEncoding
when necessary.
关于OP中提到的QWebView
中的百分比编码URL的故障,需要更多详细信息来对其进行调试.原因可能是所使用的功能和模式不同.
As for the malfunction of percent-encoded URLs in QWebView
mentioned in OP, more details are needed to debug it. Different function and different mode used could be the reason.
- RFC 3986 (符合QUrl)
- 编码表
- qitorious上qurl.cpp的来源
- RFC 3986 (which QUrl conforms)
- Encode table
- Source of qurl.cpp on Gitorious
这篇关于将具有百分比编码的QUrl转换为字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!